'Form change with JavaScript

I have two drop down lists:

<select name="branch">
  <option value="b">Blacksburg</option>
  <option value="c">Christiansburg</option>
  <option value="f">Floyd</option>
  <option value="m">Meadowbrook</option>
</select>

but I would like the second list to be different based upon what is selected from the first list. So FREX Blacksburg's might be:

<select name="room">
  <option value="Kitchen">Kitchen Side</option>
  <option value="Closet">Closet Side</option>
  <option value="Full">Full Room</option>
</select

While Christiansburg's is:

<select name="room">
  <option value="Window">Window Side</option>
  <option value="Door">Door Side</option>
  <option value="Full">Full Room</option>

and of course the options are also different for the other branches...

Is it possible to change the second drop down list based on what they select for the first one? I have used JavaScript a teensy bit, but not much so please explain in detail.



Solution 1:[1]

First, these kind of DOM modifying actions are made much easier with jQuery. It abstracts a lot of browser-specific crap away from you, making it much easier to do your thing. However, since you didn't mention the jQuery, I'll address the JavaScript issues. This is completely possible with JavaScript.

Second, you're going to want to give all of your select elements ids. This will make it much easier for JavaScript to identify them. Ids must be unique. I'm just going to follow the convention of naming the id after the name of the element.

Third, what we do is listen for the JavaScript event onchange on the select element and then do something with it (note the id attributes).

<select id="branch" name="branch" onchange="handleChange();">
  <option value="b">Blacksburg</option>
  <option value="c">Christiansburg</option>
  <option value="f">Floyd</option>
  <option value="m">Meadowbrook</option>
</select>

<select id="room" name="room">
</select>

The above code assigns the event listener handleChange to the branch select element. When a change event is fired, handleChange will be called. Now let's define the handleChange function:

<script type="text/javascript">
  var handleChange = function() {

    // get a handle to the branch select element
    var branch = document.getElementById('branch');

    // get the index of the selected item
    var index = branch.selectedIndex;

    // handle displaying the correct second select element
    if (index === 0) {

      // if the index is 0 (the first option,) call the Blacksburg function
      doBlacksburg();

    // I'll leave this up to you ;)
    } else if (index === 1) {
      // more stuff
    }
  }
</script>

Now we'll define the function that updates the second select list with Blacksburg information:

var doBlacksburg = function() {
  var blacksburg = document.getElementById('room');

  blacksburg.options[0] = new Option("Kitchen Side", "Kitchen", true, false);
  blacksburg.options[1] = new Option("Closet Side", "Closet", false, false);
  blacksburg.options[2] = new Option("Full Room", "Full", false, false);
}

That will update the second select list with the Blacksburg options. Reference for the JavaScript Option object.

That code is by no means extensive, but it should be enough to get you started. Like I said earlier, all of the above code can be done in as few as 5 lines of jQuery and it might be worth your time to look into jQuery or a similar library.

Solution 2:[2]

Yes, this is called a drilldown.

What you want to do is attach an onChange handler to your first dropdown that will grab new values based on the selected value (of the first dropdown) and populate those values into the second dropdown.

I recommend doing this with jQuery. It will make the experience much more pleasant. That being said:

var optionsMap = {
    b: {
      Kitchen: "Kitchen Side",
      Closet: "Closet Side",
      Full: "Full Room"
    },
    c: {
      Window: "Window Side",
      Door: "Door Side",
      Full: "Full Room"
    },
    ...
};

jQuery("#firstSelect").change(function() {

    /* "this" is a reference to firstSelect element. Wrapping jQuery(...)
        around it turns it into a jQuery object. Then you get the value
        of the selected element with .val() */
    var $select = jQuery(this);
    var value = $select.val();

    /* I'm doing the following to illustrate a point; in some cases 
       you may have to get it from a database with an AJAX request. 
       Basically YMMV */
    var newOptions = optionsMap[value];

    /* remove all the old options */
    jQuery("#secondSelect").find("option").remove();

    /* Iterate over the hash that you got and create new option
       objects that use the key of the hash as the option value
       and the value of the hash as the option text */
    jQuery.each(newOptions, function(option, value) {
       jQuery("#secondSelect").append(
          jQuery("<option></option>").attr("value", option)
                                     .text(value)
       );
    });
});

Solution 3:[3]

Are you familiar with / comfortable using a library like jQuery? I'd approach it with something like this:

var roomOpts = {
  b: [
    '<option value="Kitchen">Kitchen Side</option>', 
    '<option value="Closet">Closet Side</option>',
    '<option value="Full">Full Room</option>'
  ]
  ....
};

$('select[name=branch]').change(function () {
  $('select[name=room']).html(roomOpts[$(this).val()].join(''));
});

Solution 4:[4]

You can use an onchange event handler on the first list that calls a function to change the other list(s).

Solution 5:[5]

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 g.d.d.c
Solution 4 Babiker
Solution 5 sushil bharwani