简体   繁体   中英

jQuery Multiselect - Select All and with Filtered Search

When you use the search feature , and then use the select_all it does not work together, it selects "everything" as if the search made no change, but the search itself "hides" the elements. It should only select all to the items that are visible

Wondering if someone else has had this issue or knows a solution to it. Thanks again if anyone can be of assistance!

Using the jQuery MultiSelect Plugin : http://loudev.com

This is the code I'm currently using, the search utilizes the quicksearch js

$('.multiSelect').multiSelect({
  selectableHeader: "<div><a href='#' id='select-all'>select all</a></div><input type='text' class='search-input form-control' autocomplete='off' placeholder='search' style='margin-bottom:5px'>",
  selectionHeader: "<div><a href='#' id='deselect-all'>deselect all</a></div><input type='text' class='search-input form-control' autocomplete='off' placeholder='search' style='margin-bottom:5px'>",
  afterInit: function(ms){
    var that = this,
        $selectableSearch = that.$selectableUl.prev(),
        $selectionSearch = that.$selectionUl.prev(),
        selectableSearchString = '#'+that.$container.attr('id')+' .ms-elem-selectable:not(.ms-selected)',
        selectionSearchString = '#'+that.$container.attr('id')+' .ms-elem-selection.ms-selected';

    that.qs1 = $selectableSearch.quicksearch(selectableSearchString)
    .on('keydown', function(e){
      if (e.which === 40){
        that.$selectableUl.focus();
        return false;
      }
    });

    that.qs2 = $selectionSearch.quicksearch(selectionSearchString)
    .on('keydown', function(e){
      if (e.which == 40){
        that.$selectionUl.focus();
        return false;
      }
    });
  },
  afterSelect: function(){
    this.qs1.cache();
    this.qs2.cache();
  },
  afterDeselect: function(){
    this.qs1.cache();
    this.qs2.cache();
  }
});


$('#select-all').on('click',function(){
  $('.multiSelect').multiSelect('select_all');
  return false;
});

$('#deselect-all').on('click',function(){
  $('.multiSelect').multiSelect('deselect_all');
  return false;
});

jsfiddle for demonstration: http://jsfiddle.net/b8ygzqca/6/

I ran into the same issue yesterday. I too looked around for solution, but only found your post. So here is my solution. Please note that I actually updated the source code to get my solution to work. I modified the 'select_all' function:

'select_all': function () {
        var that = this,
            ms = this.$element,
            values = ms.val(),
            selectables = this.$selectableUl.find('.ms-elem-selectable').filter(':not(.' + this.options.disabledClass + ')').filter(':visible');

        ms.find('option:not(":disabled")')
            .filter(function (index) {
                var it = this,
                    msValue = selectables
                        .filter(function () {
                            return $(this).data('ms-value') === it.value;
                        })
                        .data('ms-value');
                return msValue === this.value;
            })
            .prop('selected', true);
        selectables.addClass('ms-selected').hide();
        this.$selectionUl.find('.ms-optgroup-label').show();
        this.$selectableUl.find('.ms-optgroup-label').hide();
        this.$selectionUl
            .find('.ms-elem-selection')
            .filter(':not(.' + this.options.disabledClass + ')')
            .filter(function (index) {
                return that.$selectableUl.find('#' + $(this).attr('id').replace('-selection', '-selectable') + '.ms-selected' ).length === 1;
            })
            .addClass('ms-selected')
            .show();
        this.$selectionUl.focus();
        ms.trigger('change');
        if (typeof this.options.afterSelect === 'function') {
            var selectedValues = $.grep(ms.val(), function (item) {
                return $.inArray(item, values) < 0;
            });
            this.options.afterSelect.call(this, selectedValues);
        }
    },

I added a 'that' var and then added extra filter calls on this.$selectableUl and this.$selectionUl. I also updated how the options on ms are selected. Hopefully this will work for you too.

I had the same issue and based on my tests, you don't need to change the source code.

Simply in your afterInit do prev() & find() , as below:

selectableHeader: "<div class='myDiv'><input type='text autocomplete='off'></div>"

$selectableSearch = that.$selectableUl.prev().find('input'),
$selectionSearch = that.$selectionUl.prev().find('input'),

Keep in mind for each div you have before the input , you need to do prev() . For instance:

selectableHeader: "<div class='mydDiv'><input type='text'autocomplete='off'><a href='#' id='select-all'>Add All</a></div><div class='myExtraDiv'></div>

You would need to do:

$selectableSearch = that.$selectableUl.prev().prev().find('input')

Since the first prev() , would get <div class='myExtraDiv'></div> and your 2nd prev() would fetch the correct input .

Tips: Run console.log($selectableSearch); to see what you've selected with prev()

Hope this help someone!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM