Можно ли вставить список в поле select2 и сопоставить каждый элемент в списке?
Я использую Select2 для управления большими списками данных. Пользователи выразили желание вставить список в поле Select2, чтобы сразу выбрать различные элементы, а не вручную вводить и сопоставлять каждый элемент в списке.
Я попытался использовать tokenSeparators
для разделения элементов в списке. Это и демонстрация на токенах в документации заставляют меня поверить, что то, что я надеюсь сделать, возможно, но до сих пор я не испытывал никакой радости.
Код, который я использую для создания экземпляра Select2, это:
$('input').select2({
width: 'element',
matcher: function (term, text) {
return text.toUpperCase().indexOf(term.toUpperCase()) === 0;
},
minimumInputLength: 3,
multiple: true,
data: tagList, // tagList is an array of objects with id & text parameters
placeholder: 'Manage List',
initSelection: function (element, callback) {
var data = [];
$.each(function () {
data.push({id: this, text: this});
});
callback(data);
},
tokenSeparators: [',', ', ', ' ']
});
Просто, чтобы прояснить, во всех остальных отношениях работает поле select2. Просто так, что при вставке списка в поле ничего не сопоставляется. Я хотел бы проверить все элементы в вставленном списке. Возможно ли это, и если да, то как?
Изменить: Я пробовал следующий код, но он не работает:
$('body').on('paste', '#s2id_list-unitids .select2-input', function () {
var that = this;
setTimeout(function () {
var tokens = that.value.split(/[\,\s]+/);
$('#list-unitids').val(tokens, true);console.log($('#list-unitids').select2('val'));
}, 1);
});
И вот скрипка, которую я создал: http://jsfiddle.net/KCZDu/.
Ответы
Ответ 1
select2 предоставляет параметр tokenizer
, который позволяет предварительно обработать ввод. вот возможная реализация для вашего конкретного использования:
tokenizer: function(input, selection, callback) {
// no comma no need to tokenize
if (input.indexOf(',')<0) return;
var parts=input.split(",");
for (var i=0;i<parts.length;i++) {
var part=parts[i];
part=part.trim();
// todo: check for dupes (if part is already in [selection])
// check if the part is valid
// todo: you will need a better way of doing this
var valid=false;
for (var j=0;j<unitIds.length;j++) {
if (part===unitIds[j]) { valid=true; break; }
}
if (valid) callback({id:part,text:part});
}
}
вот рабочая скрипка: http://jsfiddle.net/XcCqg/38/
также обратите внимание, что в вашей оригинальной скрипке используется select2 3.2, которая очень устарела и может не поддерживать токенизатор.
Ответ 2
В основном это переопределяет функцию вставки по умолчанию для обработки нового входного текста, этот код будет разбивать входные данные на основе разделителей, указанных в опции "tokenSeparators", а затем добавляет их все в список, разделенный, вам нужно всего лишь запустить этот кода в конце вашей страницы:
$(document).on('paste', 'span.select2', function (e) {
e.preventDefault();
var select = $(e.target).closest('.select2').prev();
var clipboard = (e.originalEvent || e).clipboardData.getData('text/plain');
var createOption = function (value, selected) {
selected = typeof selected !== 'undefined' ? selected : true;
return $("<option></option>")
.attr("value", value)
.attr("selected", selected)
.text(value)[0]
};
$.each(
clipboard.split(new RegExp(select.data('select2').options.options.tokenSeparators.map(function (a) {
return (a).replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}).join('|'))),
function (key, value) {
if (value && (!select.val() || (select.val() && select.val().indexOf('' + value) == -1))) {
select.append(createOption(value));
}
});
select.trigger('change');
});