Search through more than a hundred articles on every aspect of User.com

How to create advanced pop-up to update multiple-choice attributes value

Dawid Gulbicki
Written by Dawid Gulbicki

Learn how to build modern, accessible, and interactive pop-ups for updating multiple-choice attributes.


This guide provides a complete implementation walkthrough for creating sophisticated pop-ups specifically designed to update multiple-choice attributes, such as communication preferences or interests, within platforms like User.com. The implementation focuses on real-time validation, custom multi-select dropdowns, enhanced user experience, accessibility, modern design patterns, and seamless integration with platform capabilities.

HTML structure and semantic markup

Base pop-up structure

A well-structured pop-up starts with proper semantic HTML that ensures accessibility and screen reader compatibility:

<div class="popup-overlay" role="dialog" aria-modal="true" aria-labelledby="popup-title">
    <div class="popup-content">
        <span class="close-button" data-dismiss="true" aria-label="Close pop-up" role="button" tabindex="0">
            <!-- Close icon SVG -->
        </span>
        
        <h2 id="popup-title" class="popup-title">Customize Your Preferences</h2>
        
        <div class="form-container">
            <!-- Form content for updating preferences -->
        </div>
    </div>
</div>

Key implementation notes:

  • Use role="dialog" and aria-modal="true" for proper screen reader announcement

  • Include aria-labelledby to connect the title with the dialog

  • The data-dismiss="true" attribute enables User.com's close functionality

  • Avoid using <form> elements if your system strips them; use <div class="form-container"> instead

Input field implementation

Standard email input with real-time validation

While the primary focus is multi-choice attributes, a standard input like email is often paired for user identification:

<div class="input-group">
    <label for="email" class="label">Your Email Address</label>
    <input type="email" name="email" id="email" class="email-input" 
           placeholder="e.g., name@example.com" required>
    <div class="error-message" id="emailError" aria-live="polite">
        Please enter a valid email address.
    </div>
</div>

Implementation features:

  • aria-live="polite" announces validation errors to screen readers

  • The name attribute must match User.com attribute names

  • Error messages are hidden by default and shown via JavaScript

Custom multi-select dropdown for attributes

For complex preference selection, implement a custom dropdown that provides better UX than native select elements for updating multiple-choice attributes:

<div class="input-group">
    <label class="label">
        <span>Communications preferences</span>
    </label>
    <div class="preferences-dropdown">
        <button type="button" class="dropdown-toggle" id="dropdownToggle" 
                aria-haspopup="true" aria-expanded="false" aria-controls="dropdownMenu">
            <span id="selectedText">Select your preferences</span>
            <span class="dropdown-arrow">
                <!-- Arrow SVG -->
            </span>
        </button>
        <div class="dropdown-menu" id="dropdownMenu">
            <div class="checkbox-item">
                <input type="checkbox" name="email_preferences" value="Monthly Newsletter" id="newsletter">
                <label class="checkbox-label" for="newsletter">Monthly Newsletter</label>
            </div>
            <div class="checkbox-item">
                <input type="checkbox" name="email_preferences" value="Product Updates" id="productUpdates">
                <label class="checkbox-label" for="productUpdates">Product Updates</label>
            </div>
            <div class="checkbox-item">
                <input type="checkbox" name="email_preferences" value="Promotions" id="promotions">
                <label class="checkbox-label" for="promotions">Promotions</label>
            </div>
            <!-- Additional checkbox items for other attributes -->
        </div>
    </div>
    <div class="error-message" id="preferencesError" aria-live="polite">
        Please select at least one preference.
    </div>
</div>

Accessibility features:

  • ARIA attributes for proper screen reader interaction

  • Keyboard navigation support (arrow keys, escape key)

  • Focus management for optimal user experience

CSS implementation

Modern design system

Base styles and layout

/* Import modern font */
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap');

/* Consistent box-sizing */
*, *:after, *:before {
    box-sizing: border-box;
}

/* Pop-up overlay with backdrop */
.popup-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.7);
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 1em;
    z-index: 1000;
}

/* Main content container */
.popup-content {
    background: white;
    border-radius: 16px;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
    position: relative;
    width: 100%;
    max-width: 500px;
    display: flex;
    flex-direction: column;
    padding: 40px;
    gap: 20px;
}

Input field styling with validation states

.email-input {
    width: 100%;
    padding: 12px 15px;
    border: 1px solid #ccc;
    border-radius: 8px;
    font-family: "Poppins", sans-serif;
    font-size: 16px;
    transition: border-color 0.3s, box-shadow 0.3s;
}

.email-input:focus {
    outline: none;
    border-color: #007bff;
    box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.25);
}

/* Validation state styling */
.email-input.error {
    border-color: #dc3545;
}

.email-input.valid {
    border-color: #28a745;
}

Custom dropdown styling for multi-choice attributes

.dropdown-toggle {
    width: 100%;
    padding: 12px 15px;
    border: 1px solid #ccc;
    border-radius: 8px;
    background: white;
    font-family: "Poppins", sans-serif;
    font-size: 16px;
    color: #666;
    text-align: left;
    cursor: pointer;
    display: flex;
    justify-content: space-between;
    align-items: center;
    transition: border-color 0.3s, box-shadow 0.3s;
}

.dropdown-menu {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: white;
    border: 1px solid #ccc;
    border-top: none;
    border-radius: 0 0 8px 8px;
    max-height: 200px;
    overflow-y: auto;
    z-index: 1001;
    box-shadow: 0 4px 10px rgba(0,0,0,0.1);
    visibility: hidden;
    opacity: 0;
    transform: translateY(-10px);
    transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s;
}

.dropdown-menu.active {
    visibility: visible;
    opacity: 1;
    transform: translateY(0);
}

Custom checkbox design for attribute values

.checkbox-label::before {
    content: '';
    width: 18px;
    height: 18px;
    border: 2px solid #ccc;
    border-radius: 4px;
    display: inline-block;
    transition: background-color 0.2s, border-color 0.2s;
    flex-shrink: 0;
}

.checkbox-item input[type="checkbox"]:checked + .checkbox-label::before {
    background-color: #007bff;
    border-color: #007bff;
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3e%3c/svg%3e");
    background-repeat: no-repeat;
    background-position: center;
}

JavaScript implementation

Real-time email validation

function isValidEmail(email) {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return emailRegex.test(email) && email.length > 0;
}

function validateEmailRealTime() {
    const email = emailInput.value.trim();
    
    if (email === '') {
        // Empty field - remove styling, hide error
        emailInput.classList.remove('error', 'valid');
        emailError.classList.remove('show');
        return true;
    } else if (isValidEmail(email)) {
        // Valid email
        emailInput.classList.remove('error');
        emailInput.classList.add('valid');
        emailError.classList.remove('show');
        return true;
    } else {
        // Invalid email
        emailInput.classList.remove('valid');
        emailInput.classList.add('error');
        emailError.classList.add('show');
        return false;
    }
}

// Attach real-time validation
emailInput.addEventListener('input', validateEmailRealTime);
emailInput.addEventListener('blur', validateEmailRealTime)

Smart dropdown management for multi-choice attributes

function toggleDropdown(show, shouldFocus = false) {
    const isExpanded = show !== undefined ? show : 
        dropdownToggle.getAttribute('aria-expanded') === 'false';
    
    dropdownToggle.setAttribute('aria-expanded', isExpanded);
    dropdownMenu.classList.toggle('active', isExpanded);
    
    // Smart focus management
    if (!isExpanded && shouldFocus) {
        dropdownToggle.focus();
    }
}

// Handle dropdown interactions
dropdownToggle.addEventListener('click', (e) => {
    e.stopPropagation();
    toggleDropdown(undefined, false);
});

// Prevent dropdown from closing when clicking inside
dropdownMenu.addEventListener('click', (e) => {
    e.stopPropagation();
});

// Close dropdown when clicking outside (smart detection)
document.addEventListener('click', function(event) {
    if (!dropdownToggle.contains(event.target) && 
        !dropdownMenu.contains(event.target) && 
        !formContainer.contains(event.target)) {
        toggleDropdown(false, false);
    } else if (formContainer.contains(event.target) && 
               !dropdownToggle.contains(event.target) && 
               !dropdownMenu.contains(event.target)) {
        toggleDropdown(false, false);
    }
});

Dynamic text updates for selected attributes

function updateSelectedText() {
    const checkedCheckboxes = Array.from(checkboxes).filter(cb => cb.checked);

    if (checkedCheckboxes.length === 0) {
        selectedText.textContent = 'Select your preferences';
        dropdownToggle.classList.remove('has-selection');
    } else if (checkedCheckboxes.length === 1) {
        selectedText.textContent = checkedCheckboxes[0].value;
        dropdownToggle.classList.add('has-selection');
    } else {
        selectedText.textContent = `${checkedCheckboxes.length} preferences selected`;
        dropdownToggle.classList.add('has-selection');
    }
    
    // Clear validation errors when selections are made
    if (checkedCheckboxes.length > 0) {
        preferencesError.classList.remove('show');
    }
}

checkboxes.forEach(checkbox => {
    checkbox.addEventListener('change', updateSelectedText);
});

Form validation and submission for attribute updates

function validateAndSubmit() {
    let isValid = true;

    // Email validation
    if (!validateEmailOnSubmit()) {
        isValid = false;
    }

    // Preferences validation for multiple-choice attributes
    const isPreferenceSelected = Array.from(checkboxes).some(cb => cb.checked);
    if (!isPreferenceSelected) {
        preferencesError.classList.add('show');
        isValid = false;
    } else {
        preferencesError.classList.remove('show');
    }

    if (isValid) {
        console.log('Form is valid. Submitting preferences...');
        console.log('Email:', emailInput.value);
        console.log('Preferences:', Array.from(checkboxes)
            .filter(cb => cb.checked)
            .map(cb => cb.value));
        
        // Trigger User.com submission
        hiddenSubmitButton.click();
    }
}

Accessibility implementation

Keyboard navigation

// Dropdown keyboard support
dropdownToggle.addEventListener('keydown', function(event) {
    if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
        event.preventDefault();
        if (!dropdownMenu.classList.contains('active')) {
            toggleDropdown(true, false);
        }
    }
});

// Escape key handling
document.addEventListener('keydown', function(event) {
    if (event.key === 'Escape') {
        if (dropdownMenu.classList.contains('active')) {
            toggleDropdown(false, true);
        } else {
            closePopup();
        }
    }
});

// Enter key form submission
formContainer.addEventListener('keydown', function(event) {
    if (event.key === 'Enter' && event.target.tagName !== 'BUTTON') {
        event.preventDefault();
        validateAndSubmit();
    }
});

Screen reader support

  • Use aria-live="polite" for error announcements

  • Implement proper ARIA attributes for dropdown states

  • Include descriptive labels and alternative text

  • Ensure logical tab order through the interface

User.com integration

Hidden submit button pattern

<!-- Hidden button for User.com integration -->
<button type="submit" id="submitButton" class="hidden-submit">Submit</button>
<!-- Visible styled button for user interaction -->
<button type="button" class="submit-button" id="visibleSubmitButton">
    Save My Preferences
</button>

This pattern allows for:

  • Custom styling and validation on the visible button

  • User.com's tracking and data collection via the hidden button

  • Complete control over the submission process

Data attribute mapping for multiple-choice values

Ensure all form inputs, especially checkboxes for multi-choice attributes, have name attributes that match your User.com user attributes:

<input type="email" name="email" id="email" class="email-input" required>
<input type="checkbox" name="email_preferences" value="Monthly Newsletter" id="newsletter">

Best practices

Performance optimization

  1. Minimize DOM queries: Cache element references

  2. Use event delegation: Attach listeners efficiently

  3. Optimize CSS transitions: Use transform and opacity for smooth animations

  4. Debounce rapid events: For real-time validation on fast typing

Error handling

  1. Graceful degradation: Ensure basic functionality without JavaScript

  2. Clear error messages: Provide specific, actionable feedback

  3. Visual feedback: Use color, icons, and animation to indicate states

  4. Accessibility: Ensure errors are announced to screen readers

Mobile considerations

@media (max-width: 576px) {
    .popup-title { font-size: 20px; }
    .label, .email-input, .dropdown-toggle { font-size: 14px; }
    .submit-button { font-size: 14px; padding: 12px 20px; }
    .popup-content { padding: 30px; }
}

Testing checklist

  • Email validation works in real-time

  • Dropdown opens/closes correctly

  • Keyboard navigation functions properly

  • Screen readers announce content correctly

  • Form submits successfully to User.com

  • Close button dismisses the pop-up

  • Mobile responsive design functions

  • Error messages display and clear appropriately

  • Multiple selections update dropdown text

  • Focus management works smoothly

Conclusion

This implementation provides a robust foundation for advanced pop-ups that combine modern design, accessibility, and seamless User.com integration, specifically tailored for updating multiple-choice attributes. The real-time validation, custom dropdown functionality, and comprehensive keyboard support create an excellent user experience while maintaining compatibility with User.com's data collection and automation capabilities.

By following this guide, you can create pop-ups that not only look professional but also provide inclusive, accessible experiences for all users while effectively capturing and processing user data for multiple-choice attributes through the User.com platform.

Categories: