Dynamic Select Box: Replace Options Onchange

On this page we provide JavaScript that replaces the options in a select box based on user selection in an another select box. The example form below demonstrates. Try it by making a selection in the first select box, and you will see that the options in the second change.

Demo: Dynamic Select Box

The JavaScript provided here can be applied to multiple sets of paired select boxes. Options can be contained in optgroups.

Form Markup

The select box on the left is referred to as the controlling select box since the selection made there will control the options in the select box on the right, which is referred to as the associated select box. The associated select box can be populated with option elements using JavaScript as the page loads.

The following HTML markup generates the above form:

<form action="#" method="post" id="demoForm" class="demoForm">
    <fieldset>
        <legend>Demo: Dynamic Select Box</legend>
    
        <select name="category">
            <option value="js">JavaScripts</option>
            <option value="php">PHP Scripts</option>
            <option value="tuts">Tutorials</option> 
        </select>
        
        <select name="choices" id="choices">
            <!-- populated using JavaScript -->
        </select>
    
    </fieldset>
</form>

The option values in the controlling select box, highlighted above, are used in the object literal that holds the data for the associated select box.

Organizing Data for Paired Select Boxes

The text and values for the associated select box options are contained in an object literal.[1] Data for the example above is displayed here.

// object literal holding data for option elements
var Select_List_Data = {
    
    'choices': { // name of associated select box
        
        // names match option values in controlling select box
        js: {
            text: ['Scrolling Divs', 'Tooltips', 'Rotate Images', 'Scrollers', 'Banner Rotator'],
            value: ['scroll', 'tooltips', 'rotate', 'scrollers', 'banner']
        },
        php: {
            text: ['Random Image', 'Form Class', 'Table Class', 'Order Form'],
            value: ['random', 'form', 'table', 'order']
        },
        tuts: {
            // example without values
            text: ['Iframes', 'PHP to JS', 'Object Literals', 'Initializing JS']
        }
    
    }    
};

The Select_List_Data object literal consists of nested objects. The outermost object matches the name of the associated select box. The next level matches the values in the controlling select box. If your select box is to contain optgroups, the next level uses their labels for names. (The example in the download file demonstrates this.) The innermost level contains the text, and optionally, value arrays for your option text and value attributes.

To support additional sets of paired select boxes, supply additional objects matching the same pattern as displayed above for choices.

JavaScript for Paired Select Boxes

The two functions needed for paired select boxes, appendDataToSelect and removeAllOptions are displayed here:

// removes all option elements in select box 
// removeGrp (optional) boolean to remove optgroups
function removeAllOptions(sel, removeGrp) {
    var len, groups, par;
    if (removeGrp) {
        groups = sel.getElementsByTagName('optgroup');
        len = groups.length;
        for (var i=len; i; i--) {
            sel.removeChild( groups[i-1] );
        }
    }
    
    len = sel.options.length;
    for (var i=len; i; i--) {
        par = sel.options[i-1].parentNode;
        par.removeChild( sel.options[i-1] );
    }
}

function appendDataToSelect(sel, obj) {
    var f = document.createDocumentFragment();
    var labels = [], group, opts;
    
    function addOptions(obj) {
        var f = document.createDocumentFragment();
        var o;
        
        for (var i=0, len=obj.text.length; i<len; i++) {
            o = document.createElement('option');
            o.appendChild( document.createTextNode( obj.text[i] ) );
            
            if ( obj.value ) {
                o.value = obj.value[i];
            }
            
            f.appendChild(o);
        }
        return f;
    }
    
    if ( obj.text ) {
        opts = addOptions(obj);
        f.appendChild(opts);
    } else {
        for ( var prop in obj ) {
            if ( obj.hasOwnProperty(prop) ) {
                labels.push(prop);
            }
        }
        
        for (var i=0, len=labels.length; i<len; i++) {
            group = document.createElement('optgroup');
            group.label = labels[i];
            f.appendChild(group);
            opts = addOptions(obj[ labels[i] ] );
            group.appendChild(opts);
        }
    }
    sel.appendChild(f);
}

An anonymous function is assigned to the onchange event of the controlling select box. JavaScript is used to initially populate the associated select box based on the default selection in the controlling select box. Place the names/IDs of your form and select boxes in these two functions. Code comments provide further details.

// anonymous function assigned to onchange event of controlling select box
document.forms['demoForm'].elements['category'].onchange = function(e) {
    // name of associated select box
    var relName = 'choices';
    
    // reference to associated select box 
    var relList = this.form.elements[ relName ];
    
    // get data from object literal based on selection in controlling select box (this.value)
    var obj = Select_List_Data[ relName ][ this.value ];
    
    // remove current option elements
    removeAllOptions(relList, true);
    
    // call function to add optgroup/option elements
    // pass reference to associated select box and data for new options
    appendDataToSelect(relList, obj);
};


// populate associated select box as page loads
(function() { // immediate function to avoid globals
    
    var form = document.forms['demoForm'];
    
    // reference to controlling select box
    var sel = form.elements['category'];
    sel.selectedIndex = 0;
    
    // name of associated select box
    var relName = 'choices';
    // reference to associated select box
    var rel = form.elements[ relName ];
    
    // get data for associated select box passing its name
    // and value of selected in controlling select box
    var data = Select_List_Data[ relName ][ sel.value ];
    
    // add options to associated select box
    appendDataToSelect(rel, data);
    
}());

This example is included in the download file.

Back to top


  1. See the tutorial on Object Literals if you are unfamiliar with the syntax. ^