0

I have two select lists. Both are populated using php and mysql. When the user clicks on an organization in the first list, only events for that organization should show in the events list. The organization id is the value of the options in the organization list and the class for the options in the event list.

When I choose organization 3, two events (A and B) should show in the event list. Instead, all the event options disappear! Something must be wrong with my selector for the second menu but I'm too new to jQuery to figure it out!

jQuery

$(document).ready(function() {
    $("#pick_org").change(function() {
        var org = $(this).val();
        $("#pick_event option").hide();
        $('#pick_event option .org-'+org).show();
    });
});

HTML Form

<form action="post" method="">
<label for="pick_org">1. Pick Organization</label>    
<select name="pick_org" id="pick_org">
    <option value="1">Org 1</option>
    <option value="2">Org 2</option>
    <option value="3">Org 3</option>
    <option value="4">Org 4</option>
    <option value="5">Org 5</option>
</select>

<label for="pick_event">2. Select Event</label>
<select name="pick_event" id="pick_event">
    <option value="A" class="org-3">Event A</option>
    <option value="B" class="org-3">Event B</option>
    <option value="C" class="org-5">Event C</option>
    <option value="D" class="org-1">Event D</option>
</select>
</form>

CSS #pick_org option, #pick_event option{display:block;}

I'm loading both lists using php because my target audience doesn't always have JavaScript turned on. ;-(

Charles Sprayberry
  • 7,741
  • 3
  • 41
  • 50
dac
  • 811
  • 3
  • 12
  • 24
  • Shouldn't the fifth line be: `$('#pick_event option .'+org).show();` – grc May 08 '11 at 00:22
  • Thanks for pointing that out! When I simplified the code, I forgot to put in the org- in each class. So something else is wrong with $('#pick_event option .org'+org).show(); – dac May 08 '11 at 00:29
  • FYI also, you can't show/hide options like this in webkit, you might want to add/remove disabled attribute instead. – mVChr May 08 '11 at 00:34
  • You need to remove the " " in front of `.org-`, as in the answer given by @David. Otherwise, you asking for a **child** of an `option` element with class with prefix `org-`. But the `option` elements have no children, so the query would fail. BTW, your intent of using the `org-` prefix is a good idea because although class names that start with a digit are legal, they are not recommended. See: http://www.w3.org/TR/CSS2/syndata.html#characters – Joel Lee May 08 '11 at 00:44
  • Thanks Joel! I wasn't sure how that worked with classes of elements. And I'll take your advice to keep the prefix. – dac May 08 '11 at 01:23

2 Answers2

2

Since you can't actually hide/show options in Chrome, Safari, and I think IE as well, I created some Javascript plugins to change the options back and forth from hidden inputs upon organization selection, transferring the necessary attributes:

$.fn.changeToHidden = function () {
    this.each(function(i, ele) {
        var $ele = $(ele),
            $new = $('<input type="hidden">').attr('rel', $ele.html())
                                             .attr('value', $ele.attr('value'))
                                             .attr('class', $ele.attr('class'));
        $ele.parent().append($new);
        $ele.remove();
    });
};

$.fn.changeToOption = function () {
    this.each(function(i, ele) {
        var $ele = $(ele),
            $new = $('<option>').html($ele.attr('rel'))
                                .attr('value', $ele.attr('value'))
                                .attr('class', $ele.attr('class'));
        $ele.parent().append($new);
        $ele.remove();
    });
};

$("#pick_org").change(function() {
    var org = $(this).val();

    $("#pick_event option").changeToHidden();
    $('#pick_event input[type="hidden"].org-' + org).changeToOption();
});

This should do the trick for you and work across browsers.

See working demo →

mVChr
  • 49,587
  • 11
  • 107
  • 104
  • Awesome! Thank you, mVChr. I really like how it keeps all the options available and doesn't permanently remove them so it keeps them available if the user changes their mind and picks a different organization. Many thanks!! – dac May 08 '11 at 01:21
  • Very useful, except that it reshuffles the option orders away from the original. – Excalibur Mar 28 '12 at 13:14
  • You could alter the function to store the order as an index and append accordingly if you require. – mVChr Mar 28 '12 at 16:26
1

Given your HTML, it should be:

$(document).ready(function() {
    $("#pick_org").change(function() {
        $("#pick_event option").hide();
        $('#pick_event option.' + $(this).val()).show();
    });
});
David Fells
  • 6,678
  • 1
  • 22
  • 34
  • I tried changing my form to class="3" without the org preface and it still did not work. – dac May 08 '11 at 00:44