最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - With select2 jquery plugin with tags:true, how can you prevent choices from showing up in the dropdown that are alr

programmeradmin4浏览0评论

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 0
Add a ment  | 

3 Answers 3

Reset to default 5 +450

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./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>

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论