Chris
Chris

Reputation: 1883

Using jQuery to dynamically change options in <select> element

I've looked this up on a few other discussions but need someone to explain it to me in simple terms.

I have 2 select elements and I'd like to change the options for one depending on what is chosen for the first. I've sort of got it working by using the code below. It works perfectly for the Level 4 and Level 5 options but when I select Level 6 in the first dropdown, when you then open the second dropdown it only displays the first option and a tiny little scrollbar, so you have to scroll through each option individually.

I'd like to get it so that all of the Level 6 options (those with class="l6workshopmods") are visible when you open the dropdown, in the same way as the Level 4 and 5 are.

To clarify, here are two images - one shows how it looks when Level 4 is selected, one shows Level 6. The Level 4 is what we I'm aiming for.

When Level 4 is selected - this is how it should look

When Level 6 is selected - this doesn't look good!

Hope this makes sense!

The HTML is as follows:

<select name="course" id="workshopcourseselect">
 <option value="choosecourse">Select Course</option>
 <option value="level4">BIFM Level 4</option>
 <option value="level5">BIFM Level 5</option>
 <option value="level6">BIFM Level 6</option>
</select>

<select name="module" id="workshopmoduleselect">
 <option value="choosecourse">Select Module</option>
 <option value="401" class="l4workshopmods">FM4.01 Understanding FM</option>
 <option value="402" class="l4workshopmods">FM4.02 FM Strategy</option>
 <option value="403" class="l4workshopmods">FM4.03 People Management in FM</option>
 <option value="404" class="l4workshopmods">FM4.04 Facilities Management Support Services Operations</option>
 <option value="405" class="l4workshopmods">FM4.05 Health &amp Safety</option>
 <option value="409" class="l4workshopmods">FM4.09 Performance Measurement in FM</option>
 <option value="415" class="l4workshopmods">FM4.15 Managing Customer Service in FM</option>
 <option value="417" class="l4workshopmods">FM4.17 Property, Fabric &amp Building Services Maintenance</option>
 <option value="419" class="l4workshopmods">FM4.19 Sustainability &amp Environmental Issues</option>
 <option value="421" class="l4workshopmods">FM4.21 Procurement &amp Contract Management for FMs</option>

 <option value="501" class="l5workshopmods">FM5.01 FM Development &amp Trends</option>
 <option value="502" class="l5workshopmods">FM5.02 Organisational &amp FM Strategy</option>
 <option value="503" class="l5workshopmods">FM5.03 Managing People in FM</option>
 <option value="504" class="l5workshopmods">FM5.04 Risk Management in FM</option>
 <option value="505" class="l5workshopmods">FM5.05 Financial Management in FM</option>
 <option value="511" class="l5workshopmods">FM5.11 Managing FM Projects</option>
 <option value="516" class="l5workshopmods">FM5.16 Propert &amp Asset Management in FM</option>
 <option value="521" class="l5workshopmods">FM5.21 Managing Procurement &amp Contracts in FM</option>

 <option value="601" class="l6workshopmods">FM6.01 Strategic FM</option>
 <option value="602" class="l6workshopmods">FM6.02 FM Governance &amp Risk</option>
 <option value="603" class="l6workshopmods">FM6.03 Quality Management &amp Customer Service in FM</option>
 <option value="604" class="l6workshopmods">FM6.04 Financial Management in FM</option>
 <option value="605" class="l6workshopmods">FM6.05 Strateigc FM of Support Service Operations</option>
 <option value="609" class="l6workshopmods">FM6.09 Developing Strategic Relationships in FM</option>
 <option value="611" class="l6workshopmods">FM6.11 Corporate Responsibility &amp Sustainable FM</option>
 <option value="612" class="l6workshopmods">FM6.12 Procurement Strategy for FM</option>
 <option value="613" class="l6workshopmods">FM6.13 Property Management &amp Maintenance for FM</option>

</select>

And the jquery I've tried is:

$(document).ready(function(){

 $(".l4workshopmods, .l5workshopmods, .l6workshopmods").hide();

 $('#workshopcourseselect').change(function(){
  if ($('#workshopcourseselect').val() == "level4"){
   $(".l4workshopmods").show();
   $(".l5workshopmods, .l6workshopmods").hide();
}
  else if ($('#workshopcourseselect').val() == "level5"){
   $(".l5workshopmods").show();
   $(".l4workshopmods, .l6workshopmods").hide();
}
  else if ($('#workshopcourseselect').val() == "level6"){
   $(".l6workshopmods").show();
   $(".l4workshopmods, .l5workshopmods").hide();
}

});

});

Upvotes: 0

Views: 1416

Answers (3)

Alvaro
Alvaro

Reputation: 41605

This is happening to you because originally you had a very big select element with many options.

If you reduce the number of options of the level 5 to a couple, you will see the level 6 works correctly.

Your problem seem to be taking place because of the original render of the element. Like @nxt says, a good solution would be to append and remove elements dynamically using jQuery.

Upvotes: 0

slashingweapon
slashingweapon

Reputation: 11317

I actually couldn't get this to work at all on Chrome/MacOS X. hide() and show() for options seemed to have no effect whatsoever.

So I made a Fiddle and came up with a slightly different technique. I actually removed all of the options from the second select element. Then when the first select changes, I empty out whatever is in the second select then insert the options we want:

var l4 = $("#workshopmoduleselect .l4workshopmods").detach();
var l5 = $("#workshopmoduleselect .l5workshopmods").detach();
var l6 = $("#workshopmoduleselect .l6workshopmods").detach();
var def = $("#workshopmoduleselect option"); // everything else.  Don't detach.

$('#workshopcourseselect').change(function() {
    var level = $(this).val();
    var menu = $('#workshopmoduleselect');

    menu.empty();
    if (level == "level4")
        menu.append(l4);
    else if (level == "level5")
        menu.append(l5);
    else if (level == "level6")
        menu.append(l6);
    else
        menu.append(def);
});​

Upvotes: 1

nxt
nxt

Reputation: 1983

The hide/show on options behaves inconsistently across browsers. An easy workaround is to use detach/append instead of hide/show.

For an demo using that approach see: http://jsfiddle.net/BRTpN/1/

$.fn.linkToSelect= function(target) {
    target = $(target);
    //find all options in the target dropdown
    var options = target.find("option");
    //hide all except for the first
    options.filter(":gt(0)").detach();


    //listen for changes on the source select
    this.bind('change', function() {
        //get the selected value
        var value = $(this).val();
        //extract the level number
        value = /[0-9]+/.exec(value);
        if(value) {
            value = value[0];
        }
        //hide all target options except for the first
        options.filter(":gt(0)").detach();
        target.val('choosecourse');
        if(value || value === '0') {
            //reset the selected value 
            target.val('choosecourse');
            //show the once we want to keep:
            var classSelector = ".l"+ value + "workshopmods";
            options.filter(classSelector).appendTo(target);                       
        }        
    });
};
$("#workshopcourseselect").linkToSelect("#workshopmoduleselect");

​

Upvotes: 3

Related Questions