I am migrating over to select2 to use as a tagging plugin from another plugin but there is one gap that I am trying to figure out if select2 can support.
Let look at an example. Lets say my list of choices (coming back server side from Ajax request) is
"Dog", "Cat", "Monkey", "Giraffe"
In the old plugin I am using, after I choose one of the choices (lets say "Cat") and it shows up in the textbox, the next time I search for the same partial string (lets say "Ca"), it DOESN"T have "Cat" show up in the dropdown of choices (as it know that you have already chosen it previously)
It seems like select2 still shows the item in the dropdown when searching regardless if you have selected it already. Select2 does prevent entering if after you hit enter but this seems a bit unintuitive so I am trying to figure out if there is a way for select2 to replicate that same behavior from the other plugin (where the choices don't even show up)
As another example of this working properly, the stackoverflow tag section of a question also does the right thing. If I add "jquery" to my list of tags for this question and then search for "jquery" again, it DOESN"T show that in the list (as its already been chosen). That is the behavior that I am looking for.
Here is my current select2 code:
HTML:
<select id="Tags" name="Tags" multiple="multiple">
</select>
Javascript:
function SetupAppTags() {
$("#Tags").select2({
theme: "classic",
width: "98%",
tags: true,
ajax: {
url: "/Tag/Search",
dataType: 'json',
delay: 300,
data: function(params) {
return { q: params.term };
},
processResults: function(data, params) {
return { results: data };
},
cache: false
},
escapeMarkup: function(markup) { return markup; },
minimumInputLength: 3,
templateResult: tagFormatResult,
templateSelection: tagSelectionResult
});
}
function tagFormatResult(tag) {
if (tag.loading) {
return "Loading . . .";
} else {
if (tag.name) {
return tag.name;
}
return tag.text + " [NEW]";
}
}
function tagSelectionResult(tag) {
if (tag.name) {
return tag.name;
}
return tag.text;
}
I would think that somehow in the templateResult function there is a way to return false or something to not show that item if its already selected. Is something like this possible (can't find anything online or in the docs)
Your best option is to use the placeholder support in Select2 and include a blank option tag as your default selection.
New options can be added to a Select2 control programmatically by creating a new Javascript Option object and appending it to the control: var data = { id: 1, text: 'Barn owl' }; var newOption = new Option(data.text, data.id, false, false); $('#mySelect2').append(newOption).trigger('change');
Single select For single selects, Select2 allows you to hide the search box using the minimumResultsForSearch configuration option. In this example, we use the value Infinity to tell Select2 to never display the search box.
Select2 gives you a customizable select box with support for searching, tagging, remote data sets, infinite scrolling, and many other highly used options.
It sounds like you're looking for a custom matcher. Using one will allow you to filter the dropdown items before displaying it to the user.
var $t = $('#target');
$t.select2({
multiple: true,
tags: true,
data: ["Pasty", "Pasta", "Posters"],
matcher: function(params, option) {
var selected = $t.select2('data');
var optionSelected = selected.some(function(item) {
return (item.text === option.text);
});
if (optionSelected) return false;
return option;
}
});
#target {
width: 100%;
}
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.min.js"></script>
<link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.min.css" rel="stylesheet" />
<select id="target"></select>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With