Mark 15
(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);

Specifically, it selects the last province rather than the first, as though that .filter(':first') bit isn't working.

  • It seems to spit out errors in WebKit, too. A live page would be much easier to debug than a snippet site that's dynamically eval-ing everything. Nathan Duran almost 9 years ago
  • @Nathan: I would have, but the problem page is password-protected. Mark almost 9 years ago
  • check out <a href="http://jsbin.com">jsbin.com</a> or <a href="http://jsfiddle.net">jsfiddle.net</a> Matthew Hailwood over 8 years ago
  • opps: links dont work. Well http://jsbin.com or http://jsfiddle.net Matthew Hailwood over 8 years ago

2 answers

Mark 15
1
point
This was chosen as the best answer
(function($) {
    $.fn.cascade = function() {
        var filterSelect = $(this);
        var filterOpts = this.children('option');
        var triggerSelect = $('[name='+this.attr('rel')+']');
        var firstRun = true;

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

            if(firstRun) {
                filterOpts.filter('[rel!='+triggerValue+']').detach();
                firstRun = false;
            } else {
                filterOpts.detach().filter('[rel='+triggerValue+']').appendTo(filterSelect);
                filterSelect.val(filterSelect.children('option').filter(':first').val());
            }
        }).trigger('change');
        return this;
    }
})(jQuery);

Using filterSelect.val() instead of .attr('selected','selected') seems to work, for whatever reason.

That firstRun bit I added makes it so that the default option (set in the HTML) stays selected.

Answered almost 9 years ago by Mark
Mottie 1134
0
points

You can't hide options in IE; the only way to do it would be to completely remove the unwanted options from the select. From looking at the running code, even though you detach the options, they are still inside the select (you filtered, then appended it all back).

Some possible solutions:

  • Append the unwanted options into a hidden select.
  • Keep a hidden select with all options from which to draw wanted options to append to your second chained select
  • Check out this question on SO on how to make a chained select drawing data from a JSON object
Answered almost 9 years ago by Mottie
  • No... I'm pretty sure that's not it. detach() was specifically designed for this purpose. The options *are* being hidden IE -- that's not the problem -- it's just that the wrong option was selected by default. The whole purpose of detach() is to actually remove the elements from the DOM but keep their properties/state so that you can re-add them later. In fact, I encountered that problem earlier when I was using hide() instead. You *are* right however that the *whole* list of options is still contained in `filteredOpts`, which may have had to do with this problem. I thought `.filter('[rel='+triggerValue+']').filter(':first').attr('selected','selected')` would select the first *visible* element but that doesn't seem to be the case in IE. I'll post my solution below (just discovered it)... Mark almost 9 years ago