2

see Hide options in a select list using jQuery

The accepted answer is just plain wrong; it's not cross-browser compatible.

The most up-voted solution (remove the options but keep a clone of the full list) is what I've been doing, but it won't work for me anymore. I have to add and remove options under various scenarios, so if I replace the list with the full list (which I get via ajax) I'd then have to re-filter it again to get the options I actually want... and all these selects are based on other selects, so it gets really nasty.

My question is, is there a plugin that will actually remove the options from the DOM, but remember their positions so that can be easily re-added to the same spot later? Thus making a cross-browser hide/show for options?

Community
  • 1
  • 1
mpen
  • 256,080
  • 255
  • 805
  • 1,172

1 Answers1

0
(function($) {
    $.fn.hideOption = function(val) {
        var lastPos = 0;
        $(this).children('option').each(function() {
            var pos = $(this).data('prevPos');
            if(!pos) $(this).data('prevPos', lastPos++);
            else lastPos = pos+1;
        });
        var options = $(this).children('option[value="'+val+'"]');
        var hiddenOptions = $(this).data('hiddenOptions');
        if(!hiddenOptions) hiddenOptions = options;
        else hiddenOptions = hiddenOptions.add(options);
        $(this).data('hiddenOptions', hiddenOptions);
        options.detach();
    };

    $.fn.showOption = function(val) {
        var hiddenOptions = $(this).data('hiddenOptions');
        if(!hiddenOptions) return;
        var toAdd = null;
        if(typeof(val) !== 'undefined') {
            toAdd = hiddenOptions.filter(function() {
                return $(this).val() == val;
            });
        } else {
            toAdd = hiddenOptions;
        }
        hiddenOptions = hiddenOptions.not(toAdd);
        $(this).data('hiddenOptions', hiddenOptions);
        var visibleOptions = $(this).children();
        var select = this;
        var value = $(this).val();
        toAdd.each(function(i,hidOpt) {
            var optAdded = false;
            visibleOptions.each(function(j,visOpt) {
                if($(hidOpt).data('prevPos') >= $(visOpt).data('prevPos')) {
                    $(hidOpt).insertAfter(visOpt);
                    optAdded = true;
                    return;
                }
            });
            if(!optAdded) $(hidOpt).prependTo(select);
        }); 
        $(this).val(value);
    };
})(jQuery);

http://jsfiddle.net/mnpenner/fN2hm/14/

Please try to break it or suggest ways to improve it.

mpen
  • 256,080
  • 255
  • 805
  • 1,172