Include a javascript object that has a mapping of selections
this type of question comes up often in SPA development, and I've developed this approach. What I recommend is creating a javascript object with the different option lists, and object keys consisting of the names of the select fields which will cause sibling:after select fields to be dynamically created, by binding to the 'select' event of the dependent select element, and running a custom script to evaluate the selected option, parse your map, and then render options accordingly.
I've taken this concept, and created a pretty nifty shell, that should not only allow you to this between the two select elements you mention, but essentially allowing you to have as many depending select elements as you want... populating all of them based on the selection made in the dependent element. Here are the even cooler advantages:
- the html markup is extremely clean
- you can initialize dependencies on even the dynamically created dependee options
- the javascript code is very clean and precise
- this can easily be made modular, so it could be converted into a plugin or module with only a few lines of code
- easy to asynchronously create new options and asynchronously alter dependencies using
$.extend()
and the provided SelectOption
object
- code is built in such a way that the different option lists can be injected into the
map
object by calling custom functions
- will work on ANY ELEMENT that can trigger the
select
event. Allowing you to use non-form elements and inject dropdown type functionality and still affect other elements (**works with Bootstrap!
I have created a gist to demonstrate the concepts. I have the initial shell listed here, but check the link to ensure you have the most updated version and information on this gist. (I may turn it into a plugin)
https://gist.github.com/LongLiveCHIEF/7880119.js
form.html
<head>
<script src="jquery.js"></script><!-- use .js for easier DOM manipulation, can be done without, using the native DOM api -->
<script src="selection-map.js"></script>
</head>
<body>
<!-- select name="" values will be used inside the map object to initialize watch -->
<!-- the custom data-selmap-cascade="" property initializes the dynamic functionality, and the value should be an
-- string array format, where the values are the names of the select field whose options will depend on this
-- elements selected option
-->
<select data-selmap-cascade="['secondselect','fourthselect']" name="firstselect">
<option data-selmap-set-cascade="['second-select : set2', 'fourth-select : set1']" value="0" selected="selected">Choose...</option>
<!-- list other options here, using the data-selmap-showselectfields settings for each dependent select field -->
</select>
<select class="selmap" name="secondselect">
<!-- will be created via selection-map.js -->
</select>
</body>
selection-map.js
// first we map our dependencies
var map = {
secondselect: [ //high level keys are the fields that will cause cascades
'set1' : {[new SelectOption('','','')],[new SelectOption('','','')],[new SelectOption('','','')]} // this is an option list, with gets a name as a key
'set2' : {[new SelectOption('','','')],[new SelectOption('','','')],[new SelectOption('','','')]},
'set3' : {[new SelectOption('','','')],[new SelectOption('','','')],[new SelectOption('','','')]},
],
fourthselect: [
'set1' : {[new SelectOption('','','')],[new SelectOption('','','')],[new SelectOption('','','')]}
]
};
// now we make it easy to inject select options at any point
var SelectOption = function(text, value, dependenSelectFields){
return {}; //retun object with properties corresponding to the attributes and values of a specific option
}
//and now we kick off processing
var $primaryElements = $.data('selmap-cascade'); // create a collection consisting of any and all elements with selmap-cascade data option
//here we act when any designated dependent field has a selection change
$primaryelements.select(function(){
var mapkey = $(this + ':selected').data('selmap-set-cascade'); // get the data that will allow us to grab the proper select options for the dependent elements
//and now we render the correct option into the correct place in the DOM
});