0

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();
}

});

});
4
  • 5
    By £, don't you mean $? You know, I was a little stressed, but when I saw this I found it amusing in many levels, which made me feel better Commented Nov 20, 2012 at 16:51
  • "bit convoluted I know" then clean up your question so maybe someone will be able to help you! Commented Nov 20, 2012 at 16:51
  • 5
    british.jquery.com ;-) Commented Nov 20, 2012 at 16:55
  • show() and hide() methods for select options have a troubles in IE. Commented Nov 20, 2012 at 17:17

3 Answers 3

3

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");

​
Sign up to request clarification or add additional context in comments.

3 Comments

This worked a treat, although I do have one small query. If I were to add further options to the dropdowns at a later stage, how would I integrate this into the function? I'm fairly new to jQuery so the intricacies of this code are a bit beyond me, but I want to try and understand it properly rather than just copying, pasting and leaving it!
@Chris if you keep the same convention (use value=levelXX in the first select and lXXworkshopmods as class in the second select) you don't need to change the jquery function. The function as it currently is assumes that the value of the first select contains a number and that the same number is part of the class of the options in the second select
@Chris I've added some extra comments at jsfiddle.net/BRTpN/2 to explain the different parts
1

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);
});​

2 Comments

The solution by @nxt is admittedly better designed, although a little harder to read.
Based on your comment I've gone with @nxt's solution, although I have to say I don't totally understand how it works (although the main thing is it does work!). Thanks for taking the time to find a solution though!
0

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.

2 Comments

My solution removes the options after the select is rendered so it won't save any data transfer and actually might slightly increase loading speed because we modify the dom after rendering. To increase rendering speed it should be modified to keep the options in a javascript array instead of rendering & detaching them.
True, i just took a fast look at your answer :) Sorry.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.