views:

70

answers:

2

I'm trying to write a function to update the "multiple" select (the second one below) such that when I select Method1 (from the first select), only the options 1A, 1B and 1C appears in the second select, and likewise for 2A, 2B... only when I select Method2. Is there a way to do this. Please help. Many thanks in advance.

<select name="choices" onchange="updatesub()">
    <option>Method1</option>
    <option>Method2</option>
</select>

<select multiple="multiple" name="sub">
    <option>1A</option>
    <option>1B</option>
    <option>1C</option>

    <option>2A</option>
    <option>2B</option>
    <option>2C</option>
</select>
+1  A: 

Hiding the elements is not something you should be doing, really (and thus, it's not possible in Webkit or IE). You could disable them, though. Using this HTML:

<select id="choices">
    <option value="grp1">Method 1</option>
    <option value="grp2">Method 2</option>
</select>

<select id="sub" multiple>
    <optgroup label="Method 1" id="grp1">
        <option>1A</option>
        <option>1B</option>
        <option>1C</option>
    </optgroup>
    <optgroup label="Method 2" id="grp2">
        <option>2A</option>
        <option>2B</option>
        <option>2C</option>
    </optgroup>
</select>

And jQuery:

$(document).ready(function(){
    $("#choices").change(function(){
        $("#sub optgroup").attr("disabled", true);
        $("#sub optgroup#"+$(this).val()).attr("disabled", false);
    });
    $("#choices optgroup:not(#"+$("#choices option:selected").val()+")").attr("disabled", true);
});

You'll basically disable the options that are not applicable, which is the "proper" way to go about things. (And use <optgroup>, that's what it's for!)

Disclaimer: I couldn't get this working in Safari, but according to HTML4.01 and HTML5 specs, this should work. I'm not sure what's going on.

You
@You: And here is working demo:http://jsbin.com/ahefu :)
Sarfraz
@sAc - Tried the demo. It doesn't work in Safari or IE. Were you testing with Firefox?
patrick dw
@patrick dw: That's true, i tested it in FF only
Sarfraz
@sAc - That must by why. Firefox allows hiding of `<option>` elements. Other browsers do not.
patrick dw
That's the flip-side of this method. You're not really supposed to be hiding the elements anyway; using the `disabled` property of the `<optgroup>` element. However, I could not get that working in Safari either. Nonetheless, I have edited my answer to use that (better) method.
You
+4  A: 

I don't think there's cross browser support for hiding select options.

Here's one way to do it. Uses a more jQuery like method of handling events, so you'll need to remove the inline onchange from the HTML.

Try it out: http://jsfiddle.net/W9KvT/

var options = [
    ['1A','1B','1C'],
    ['2A','2B','2C']
];

$('select[name=choices]').change(function() {
    var idx = $(this).children(':selected').index();
    var set = '';
    for(var i = 0, len = options[idx].length; i < len; i++) {
        set += '<option>' + options[idx][i] + '</option>';
    }
    $('select[name=sub]').html(set);
}).change();

If you don't want to generate these on the fly each time, you could create each option string, and save them in the array, loading them in a similar manner.

Try it out: http://jsfiddle.net/W9KvT/1

var options = [
    '<option>1A</option><option>1B</option><option>1C</option>',
    '<option>2A</option><option>2B</option><option>2C</option>'
];

$('select[name=choices]').change(function() {
    var idx = $(this).children(':selected').index();
    $('select[name=sub]').html(options[idx]);
}).change();

EDIT: As noted by @You, in order to ensure compatibility with browsers that have javascript disabled, it is best to have all the available options available on page load. Then you can use the code above to overwrite them for js browsers.

The <optgroup> elements from @You's answer would be an excellent idea in that case.

patrick dw
I would second this but unfortunately i have consumed all my votes for today :(
Sarfraz
@sAc - Thats alright. :o)
patrick dw
It works in all browsers, but it will break functionality for non-JS visitors.
You
@You - Not if you supply `<select>` with all the `<option>` elements at the initial page load. This method will simply overwrite them if js is enabled. I just happened to delete them from the example. Here's an updated example. http://jsfiddle.net/W9KvT/3/ Of course `<optgroup>` could be used too.
patrick dw
Very true, but it is something you need to have in mind, so that you don't forget including (and updating, whenever necessary) these "static" `<option>` elements. You must always be vigilant when using JS; otherwise you might unintentionally break stuff.
You
@You - True. Point well taken. :o) I'll update with that suggestion.
patrick dw