I have select2 multi select field in my form where I want to remove the selected option from the dropdown list after it is selected and again add it to the list if it is removed
Another approach to hide the selected values, is to use the dropdown templateResult option to return null
when the value is marked as selected.
function hideSelected(value) {
if (value && !value.selected) {
return $('<span>' + value.text + '</span>');
}
}
$(document).ready(function() {
$('#dynamicAttributes').select2({
allowClear: true,
placeholder: {
id: "",
placeholder: "Leave blank to ..."
},
minimumResultsForSearch: -1,
width: 600,
templateResult: hideSelected,
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.2/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.2/js/select2.min.js"></script>
<select id="dynamicAttributes" multiple="true" data-tags="true">
<option value="1">A</option>
<option value="2">B</option>
<option value="3">C</option>
</select>
Remove (UnSelect) item from select2 multiple selected items
first step: add 'multiple' css class to your select2 element to get the true element which you want
<select class="multiple">
....
</select>
$('select.multiple').on('select2:selecting', function (e) {
var select = this;
var idToRemove = '0';
var selections = $(select).select2('data');
var Values = new Array();
for (var i = 0; i < selections.length; i++) {
if (idToRemove !== selections[i].id) {
Values.push(selections[i].id);
}
}
$(select).val(Values).trigger('change');
});
my solution was modified the select2.js (the core, version 4.0.3) in the line #3158. Add the following verification :
if ($option[0].selected == true) {
return;
}
With this verification, we can exclude from the dropdown list, the selected ones. And if you write the name of a selected option, appear the text of option "noResult" .
Here the complete code:
SelectAdapter.prototype.query = function (params, callback) {
var data = [];
var self = this;
var $options = this.$element.children();
$options.each(function () {
var $option = $(this);
if (!$option.is('option') && !$option.is('optgroup') ) {
return;
}
if ($option[0].selected == true) {
return;
}
var option = self.item($option);
var matches = self.matches(params, option);
if (matches !== null) {
data.push(matches);
}
});
callback({
results: data
});
};
$(document).ready(function(){
$('#dynamicAttributes').select2({
allowClear: true,
minimumResultsForSearch: -1,
width: 600
});
});
this make a error when click the remove sign button
TypeError: this.placeholder is undefined
use
$(document).ready(function(){
$('#dynamicAttributes').select2({
allowClear: true,
minimumResultsForSearch: -1,
width: 600,
placeholder: 'past your placeholder'
});
});
I find a way to make the selected values not to appear anymore on the selection pop up list
On the documentation you can they have list of events Select2 events
open
I make use of these select2 event open to hide the selected values
Here is the javascript ::
$(document).ready(function() {
$('#dynamicAttributes').select2({
allowClear: true,
minimumResultsForSearch: -1,
width: 600
});
// override the select2 open event
$('#dynamicAttributes').on('select2:open', function () {
// get values of selected option
var values = $(this).val();
// get the pop up selection
var pop_up_selection = $('.select2-results__options');
if (values != null ) {
// hide the selected values
pop_up_selection.find("li[aria-selected=true]").hide();
} else {
// show all the selection values
pop_up_selection.find("li[aria-selected=true]").show();
}
});
});
Here is a DEMO
Hope it helps.
Part #1 of Q:
You can do a CSS trick to hide selected item
like this:
.select2-results__option[aria-selected=true] {
display: none;
}
Part #2 of Q:
Also you can do a JQuery trick to force selected items
to end of tags box, ( by getting selected item on select, detach it (remove it), then reAppend it to tags box, then call "change function" to apply changes ):
$("select").on("select2:select", function (evt) {
var element = evt.params.data.element;
var $element = $(element);
$element.detach();
$(this).append($element);
$(this).trigger("change");
});
Finally Updated JsFiddle, I hope it works for you, Thanks !
Edit #1
You can Clear All Selected
by this call (apply Null values):
$("#dynamicAttributes").val(null).trigger("change");
on Button:
$('#btnReset').click(function() {
$("#dynamicAttributes").val(null).trigger("change");
});
Updated Fiddle #2