Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

With select2 jquery plugin with tags:true, how can you prevent choices from showing up in the dropdown that are already selected?

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)

like image 415
leora Avatar asked Sep 26 '15 13:09

leora


People also ask

How do I stop Select2 from auto selecting the first option?

Your best option is to use the placeholder support in Select2 and include a blank option tag as your default selection.

How do you add new option if not exist in the list using Select2?

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');

How do I hide Select2 search box?

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.

What is the use of Select2 in jQuery?

Select2 gives you a customizable select box with support for searching, tagging, remote data sets, infinite scrolling, and many other highly used options.


1 Answers

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>
like image 54
Etheryte Avatar answered Oct 09 '22 21:10

Etheryte