2

I wrote this nifty function to filter select boxes when their value is changed...

$.fn.cascade = function() {
    var opts = this.children('option');
    var rel = this.attr('rel');
    $('[name='+rel+']').change(function() {
        var val = $(this).val();
        var disp = opts.filter('[rel='+val+']');
        opts.filter(':visible').hide();
        disp.show();
        if(!disp.filter(':selected').length) {
            disp.filter(':first').attr('selected','selected');
        }
    }).trigger('change');
    return this;
}

It looks at the rel property, and if the element indicated by rel changes, then it filters the list to only show the options that have that value... for example, it works on HTML that looks like this:

<select id="id-pickup_address-country" name="pickup_address-country">
  <option selected="selected" value="CA">Canada
  </option>
  <option value="US">United States
  </option>
</select>

<select id="id-pickup_address-province" rel="pickup_address-country" name="pickup_address-province">
  <option rel="CA" value="AB">Alberta
  </option>
  <option selected="selected" rel="CA" value="BC">British Columbia
  </option>
  <option rel="CA" value="MB">Manitoba
  </option>...
</select>

However, I just discovered it doesn't work properly in IE (of course!) which doesn't seem to allow you to hide options. How can I work around this?


Here's what I've got now:

(function($) {
    $.fn.cascade = function() {
        var filteredSelect = $(this);
        var filteredOpts = this.children('option');
        var triggerSelect = $('[name='+this.attr('rel')+']');

        triggerSelect.change(function() {
            var triggerValue = $(this).val();

            filteredOpts.detach()
                .filter('[rel='+triggerValue+']').appendTo(filteredSelect)
                .filter(':first').attr('selected','selected');
        }).trigger('change');
        return this;
    }
})(jQuery);

Which does work in IE, but still has two problems. The .filter(':first').attr('selected','selected'); bit doesn't seem to do anything in IE (it should select the first visible element). Since I've been using appendTo it currently defaults to the last. And the other problem is that since I detach all the elements immediately, you can't have default values in your HTML.

mpen
  • 272,448
  • 266
  • 850
  • 1,236

1 Answers1

2

Options cannot be marked hidden. You must use the SelectElement.add(option) and SelectElement.remove(index)...

Here is a link to remove and add select Options in the same order. How can I restore the order of an (incomplete) select list to its original order?

Here is a link where I made a post for just doing the most simple thing How to hide optgroup/option elements?

Note in my post the try catch. This is necessary when adding elements expecially when making the site usable in firefox and IE.

Community
  • 1
  • 1
John Hartsock
  • 85,422
  • 23
  • 131
  • 146
  • The above links should get you fixed up. – John Hartsock May 04 '10 at 03:06
  • I'm not sure I like that code at all... DVK's code looks like an inefficient/non-jQuery mess. Also removing elements rather than detaching them will strip any events. – mpen May 05 '10 at 18:28
  • some of that code could get cleand up but as for your comment "detaching them will strip any events". What events would you attach to an option element. your events should live on the select element – John Hartsock May 05 '10 at 19:17