使用带有 tags:true 的 select2 jquery 插件,您如何防止选项出现在已经选择的下拉列表中?

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

我正在从另一个插件迁移到 select2 to use as a tagging plugin,但我想弄清楚 select2 是否可以支持一个缺口。

让我们看一个例子。假设我的选择列表(从 Ajax 请求返回服务器端)是

"Dog", "Cat", "Monkey", "Giraffe"

在我使用的旧插件中,在我选择其中一个选项(比如说 "Cat")并且它显示在文本框中时,下次我搜索相同的部分字符串时(比如说"Ca"),它没有 "Cat" 显示在选项的下拉列表中(因为它知道您之前已经选择了它)

似乎 select2 在搜索时仍会在下拉列表中显示该项目,无论您是否已经选择它。 Select2 确实会在您按下回车键后阻止输入,但这似乎有点不直观,所以我想弄清楚 select2 是否有办法从其他插件复制相同的行为(选择甚至没有显示)

作为此正常工作的另一个示例,问题的 Whosebug 标记部分也做了正确的事情。如果我将 "jquery" 添加到这个问题的标签列表中,然后再次搜索 "jquery",它 DOESN"T 会在列表中显示(因为它已经已被选中)。这就是我要寻找的行为。

这是我当前的 select2 代码:

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;
}

我认为在 templateResult 函数中有某种方法可以 return false 或不显示该项目(如果它已被选中)的方法。这样的事情可能吗(在网上或文档中找不到任何东西)

您应该考虑更改 templateResult 函数...

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

您可以像下面这样简单地实现,

您需要使用 CSS

隐藏所选选项

$('select').select2();
.select2-container--default .select2-results__option[aria-selected=true] {
    display: none;
}
<link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.min.css" rel="stylesheet" />
<script src="https://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>

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

听起来您正在寻找 a custom matcher。使用一个将允许您在向用户显示之前过滤下拉项。

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>