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’.
Thanks a lot for your help in advance.
Özkan
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’.
Thanks a lot for your help in advance.
Özkan
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:
After choosing “Select all matches”:
Now I search for something else (“cd”):
Choosing “Select all matches” replaces the previous selections:
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');
};
};
I hope this helps you.
Hi there,
I’ve found this jsfiddle Select2 select all/none - JSFiddle - Code Playground (which doesn’t work for me)
if you encounter the same problem, i’ve edited his code with the below:
/*
Define the select all adapter in a way that it's reusable
*/
$.fn.select2.amd.define('select2/selectAllAdapter', [
'select2/utils',
'select2/dropdown',
'select2/dropdown/attachBody'
], function (Utils, Dropdown, AttachBody) {
function SelectAll() {}
SelectAll.prototype.render = function (decorated) {
var self = this,
$rendered = decorated.call(this),
$selectAll = $(
'<button class="btn btn-xs btn-default" type="button" style="margin-left:6px;"><i class="fa fa-check-square-o"></i> Select All</button>'
),
$unselectAll = $(
'<button class="btn btn-xs btn-default" type="button" style="margin-left:6px;"><i class="fa fa-square-o"></i> Unselect All</button>'
),
$btnContainer = $('<div style="margin-top:3px;">').append($selectAll).append($unselectAll);
if (!this.$element.prop("multiple")) {
// this isn't a multi-select -> don't add the buttons!
return $rendered;
}
$rendered.find('.select2-dropdown').prepend($btnContainer);
var $select2 = $(this.$element[0]);
$selectAll.on('click', function () {
var vals = [];
$select2.find('option').each(function () {
vals.push(this.value);
});
$select2.val(vals); // Select the options with an array
$select2.trigger('change'); // Notify any JS components that the value changed
});
$unselectAll.on('click', function (e) {
$select2.val(null); // Select the option with null value
$select2.trigger('change'); // Notify any JS components that the value change
});
return $rendered;
};
return Utils.Decorate(
Utils.Decorate(
Dropdown,
AttachBody
),
SelectAll
);
});
make sure you have the select2.full.min.js release . otherwise the code won’t work as it uses AMD