Select All of search result


#1

Hi All,

is it possible to select all options of search result of multiple selection? In the screen shot below, I need to provide users with the possibility to select all options starting with ‘FC’.

image

Thanks a lot for your help in advance.
Özkan


#2

Hi, Özkan—

Select2 doesn’t support a “select all” feature out of the box; however, you can write code to do it yourself. One way I can think of to do that is to use a custom sorter function . The sorter function receives an array of all the matching items, and should return an array with the items sorted in the order you want to display them in the dropdown.

In your case, you don’t need to change the order of the items, but you can insert another item at the beginning of the list of matched items, that says something like “Select all matches”. You also need to include the list of all the matching items’ IDs in the new item, so they are available for the next step.

The next step is to listen for the select2:select event, so when your “Select all” item is selected, you can programmatically replace that selection with the matched items.

I coded up the following demo:

  const addSelectAll = matches => {
    if (matches.length > 0) {
      // Insert a special "Select all matches" item at the start of the 
      // list of matched items.
      return [
        {id: 'selectAll', text: 'Select all matches', matchIds: matches.map(match => match.id)},
        ...matches
      ];
    }
  };

  const handleSelection = event => {
    if (event.params.data.id === 'selectAll') {
      $('#my-select').val(event.params.data.matchIds);
      $('#my-select').trigger('change');
    };
  };

  $('#my-select').select2({
    minimumInputLength: 2,
    multiple: true,
    sorter: addSelectAll,
    width: '15rem', // you might not need to specify this
  });
  $('#my-select').on('select2:select', handleSelection);

This works with hard-coded options (either in the HTML or the JavaScript), and I believe it would work with options retrieved via AJAX, although I can’t easily test this.

Note that I had to set a minimumInputLength, otherwise the addSelectAll callback receives all the items in the list when there is no input term, and it outputs the “Select all matches” item followed by all the items in the <select>. If you actually want to allow users to select all items, then you could omit the minimumInputLength configuration option. (In that case you might want to change the “select all” item’s text to something like “Select all items below”.)

Here are some screen shots showing how it works:
2019-10-04%2022_20_06-Select2%20select%20all%20matches

After choosing “Select all matches”:
2019-10-04%2022_20_51-Select2%20select%20all%20matches

Now I search for something else (“cd”):
2019-10-04%2022_21_30-Select2%20select%20all%20matches

Choosing “Select all matches” replaces the previous selections:
2019-10-04%2022_21_59-Select2%20select%20all%20matches

If you want to retain the current selections, then you’ll need to merge the current selections with the new ones in the handleSelection callback:

  const handleSelection = event => {
    if (event.params.data.id === 'selectAll') {
      curSelIds = $('#my-select').val() || [];
      $('#my-select').val([...curSelIds, ...event.params.data.matchIds]);
      $('#my-select').trigger('change');
    };
  };

2019-10-04%2022_45_40-Select2%20select%20all%20matches
2019-10-04%2022_46_17-Select2%20select%20all%20matches

I hope this helps you.