С плагином jquery select2 с тегами: true, как вы можете предотвратить появление вариантов в раскрывающемся списке, которые уже выбраны?

Я перехожу на select2 для использования в качестве плагина тегов из другого плагина, но есть один пробел, который я пытаюсь понять out, если select2 может поддерживать.

Давайте посмотрим на пример. Допустим, мой список вариантов (возвращающийся на серверную сторону из запроса Ajax)

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

В старом плагине, который я использую, после того, как я выберу один из вариантов (скажем, «Кот»), и он появится в текстовом поле, в следующий раз, когда я буду искать ту же частичную строку (скажем, «Ca»), он НЕ «У вас есть «Кошка» в раскрывающемся списке вариантов (так как она знает, что вы уже выбрали ее ранее)

Кажется, что select2 по-прежнему показывает элемент в раскрывающемся списке при поиске, независимо от того, выбрали ли вы его уже. Select2 предотвращает ввод, если после нажатия Enter, но это кажется немного неинтуитивным, поэтому я пытаюсь выяснить, есть ли способ для select2 воспроизвести такое же поведение из другого плагина (где выбор даже не отображается)

В качестве еще одного примера того, как это работает правильно, раздел вопроса с тегом stackoverflow также работает правильно. Если я добавлю «jquery» в свой список тегов для этого вопроса, а затем снова найду «jquery», он НЕ НЕТ покажет это в списке (поскольку он уже выбран). поведение, которое я ищу.

Вот мой текущий код 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 есть способ вернуть false или что-то еще, чтобы не показывать этот элемент, если он уже выбран. Возможно ли что-то подобное (не могу найти ничего в Интернете или в документах)


person leora    schedule 26.09.2015    source источник


Ответы (3)


Похоже, вы ищете собственный сопоставитель. Использование одного из них позволит вам отфильтровать элементы раскрывающегося списка перед его отображением пользователю.

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>

person Etheryte    schedule 03.10.2015
comment
Знаете ли вы, в чем разница между пользовательским сопоставлением и возвратом null в функции templateResult? - person leora; 06.10.2015
comment
@leora Я просмотрел документы и провел некоторую отладку, оба варианта возможны, поскольку они предлагают несколько дублирующиеся функции. Из документации: [Select2 использует] matcher, чтобы определить, следует ли отображать [каждый результат]. Кроме того, templateResult может возвращать null, что предотвратит отображение параметра в списке результатов. . Как видите, они позволяют пользователю делать одно и то же по разным маршрутам. Почему библиотека была разработана таким образом, не слишком понятно, но причина, вероятно, в простоте использования, если вы хотите изменить только то или иное в незначительных деталях. - person Etheryte; 06.10.2015

Вы должны посмотреть на изменение функции templateResult...

Функция templateResult должна возвращать строку, содержащую отображаемый текст, или объект (например, объект jQuery), содержащий данные, которые должны отображаться. Он также может возвращать значение null, что предотвратит отображение параметра в списке результатов.

https://select2.github.io/options.html#templateSelection

person JamesHalsall    schedule 26.09.2015
comment
спасибо Джеймс. Я обновил ответ ytour решением, которое, кажется, работает. Пожалуйста, дайте мне знать, если вы обнаружите какие-либо проблемы с моим решением или у вас есть другое предложение. - person leora; 26.09.2015
comment
На самом деле, я только что понял, что приведенный выше ответ, который я добавил к вашему вопросу, НЕ работает, как если бы вы удалили тег, он все еще отображается в списке, поэтому у вас возникает проблема, когда, если вы удаляете тег и хотите добавить его обратно, он не работает. т позволить вам .. Итак, я вернулся к чертежной доске. Вы знаете, как я могу предотвратить? - person leora; 03.10.2015
comment
извините, не знаю :( Я никогда раньше этим не пользовался, но из документации показалось, что это сработает - person JamesHalsall; 06.10.2015

Вы можете добиться этого просто, как показано ниже,

Вам нужно скрыть выбранные параметры с помощью 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>

person jlocker    schedule 03.10.2015
comment
Это трюк, который работает, но он может вызвать другие проблемы, такие как выбор клавиатуры. - person Marcos Pérez Gude; 03.10.2015
comment
Эй, не волнуйтесь, я делаю это в проекте, и это работает, но в других ситуациях я не могу написать этот трюк. В зависимости от потребностей ОП. Удачи! - person Marcos Pérez Gude; 03.10.2015