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 (ing 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)
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 (ing 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)
Share Improve this question edited Oct 3, 2015 at 13:31 leora asked Sep 26, 2015 at 13:22 leoraleora 197k368 gold badges906 silver badges1.4k bronze badges 03 Answers
Reset to default 5 +450It 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./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare./ajax/libs/select2/4.0.0/js/select2.min.js"></script>
<link href="//cdnjs.cloudflare./ajax/libs/select2/4.0.0/css/select2.min.css" rel="stylesheet" />
<select id="target"></select>
You should look at changing the templateResult
function...
The templateResult function should return a string containing the text to be displayed, or an object (such as a jQuery object) that contains the data that should be displayed. It can also return null, which will prevent the option from being displayed in the results list.
https://select2.github.io/options.html#templateSelection
You can achieve this simply like below,
You need to hide the selected options using CSS
$('select').select2();
.select2-container--default .select2-results__option[aria-selected=true] {
display: none;
}
<link href="//cdnjs.cloudflare./ajax/libs/select2/4.0.0/css/select2.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare./ajax/libs/select2/4.0.0/js/select2.min.js"></script>
<select id="Tags" name="Tags" multiple="multiple">
<option value="1">first</option>
<option value="2">second</option>
<option value="3">third</option>
<option value="4">fourth</option>
</select>