var jsonData = '{"lists":{"people":{"1":"Jack Sparrow","2":"Captain Barbosa","3":"Davy Jones"},"locations":{"1":"The Black Pearl","2":"The Flying Dutchman"},"disciplines":{"1":"Fighting","2":"Looting","3":"Tentacles","4":"Undead","5":"Rope Tricks"}},"rels":{"people":{"locations":{"1":["1","2"],"2":["1"],"3":["2"]},"disciplines":{"1":["1","2","5"],"2":["1","2","4"],"3":["1","3"]}},"disciplines":{"people":{"1":["1","2","3"],"2":["1","2"],"3":["1","3"],"4":["2"],"5":["1"]},"locations":{"1":["1","2"],"2":["1","2"],"3":["1","2"],"4":["1","2"],"5":["2"],"6":["1","2"]}},"locations":{"people":{"1":["1","2"],"2":["1","3"]},"disciplines":{"1":["1","2","4","5"],"2":["1","2","3","5"]}}}}'; var data = JSON.parse(jsonData); function intersect_safe(a, b) { var ai=0, bi=0; var result = new Array(); while( ai < a.length && bi < b.length ) { if (a[ai] < b[bi] ){ ai++; } else if (a[ai] > b[bi] ){ bi++; } else /* they're equal */ { result.push(a[ai]); ai++; bi++; } } return result; } var changeOpts = function() { var currentSelections = {}; $('#selects select').each( function(idx) { var id = $(this).attr('id'); var val = $(this).val() ? $(this).val() : ""; $.each( data.rels[id], function(index, value) { if (val == '' || id == index) { var dval = []; $.each(data.lists[index], function(vi, vv) { dval.push(vi); } ); } else { var dval = value[val]; } if (typeof(currentSelections[index]) == 'undefined') { currentSelections[index] = dval.sort(); } else { currentSelections[index] = intersect_safe(currentSelections[index], dval.sort()); } }); }); $.each(currentSelections, function(index, value) { var current = $('#'+index).val(); $('#'+index) .empty('option') .append('<option value="">Any</option>'); $.each(value, function(idx,val) { var opt = $('<option value="'+val+'">'+data.lists[index][val]+'</option>'); if (val == current) { opt.attr('selected', 'selected'); } opt.appendTo('#'+index); }); } ); } // use the change function to set up the locations and disciplines changeOpts(); $('#selects select').change( changeOpts );
<div id="selects"> <label for="people"><span>Character</span><select id="people"></select></label> <label for="locations"><span>Ship</span><select id="locations"></select></label> <label for="disciplines"><span>Skills</span><select id="disciplines"></select></label> </div>
#selects label { float: left; width: 150px; margin-right: 5px; } #selects label select, #selects label span { display: block; width: 150px; }