Как предотвратить дублирование с помощью Bootstrap Tokenfield при использовании автозаполнения jQuery Ui
Я пытаюсь реализовать Bootstrap Tokenfield с автозаполнением jQuery Ui и до сих пор я смог это сделать, за исключением того, что я не могу предотвратить дубликаты в поле ввода, поэтому, к сожалению, мой пользователь может выбрать одно и то же значение дважды.
в моем поиске я обнаружил, что Bootstrap Tokenfield имеет способ предотвращение дублирования. Однако я не знаю, как применить к моему коду, потому что мне кажется, что он идет с Twitter typeahead и не jQuery Ui.
Как я могу предотвратить дублирование с помощью Bootstrap TokenField с помощью автозаполнения jQuery Ui ?
Это мой загрузочный код TokenField на основе автозаполнения jQuery ui
$('.tokenfield').tokenfield({
autocomplete: {
source: [
{
"id": "1",
"value": "Ferdine Faithfull"
},
{
"id": "2",
"value": "John Carta"
},
{
"id": "3",
"value": "Mezane Smith"
}
],
delay: 100
},
showAutocompleteOnFocus: true
});
и ниже то, что я нашел на Github, чтобы предотвратить дублирование, хотя я думаю, что это для Typeahead
$('#my-tokenfield').on('tokenfield:createtoken', function (event) {
var existingTokens = $(this).tokenfield('getTokens');
$.each(existingTokens, function(index, token) {
if (token.value === event.attrs.value)
event.preventDefault();
});
});
4 ответов
Я думаю, что вы сделали все это, все, что вам остается сделать, это заменить класс
поэтому после первого кода вместо второго кода напишите
$('.tokenfield').on('tokenfield:createtoken', function (event) {
var existingTokens = $(this).tokenfield('getTokens');
$.each(existingTokens, function(index, token) {
if (token.value === event.attrs.value)
event.preventDefault();
});
});
разница вот ваш класс, который должен быть применен, и он работает как для Twitter Typeahead и jQuery Ui
это предотвращает перечисление элементов, которые уже были добавлены в качестве токенов:
$('.tokenfield').on('tokenfield:createdtoken tokenfield:removedtoken', function (event) {
var field = $(this);
var currentTokens = field.tokenfield('getTokens');
var originalSource = field.data('bs.tokenfield').options.autocomplete.source;
var newSource = originalSource.slice(); //clone original autocomplete source
for (var i = newSource.length - 1; i >= 0; i--) {
for (var j = currentTokens.length - 1; j >= 0; j--) {
if (JSON.stringify(currentTokens[j].label) == JSON.stringify(newSource[i])
|| JSON.stringify(currentTokens[j]) == JSON.stringify(newSource[i]) ) {
//remove the token from the newSource
var index = newSource.indexOf(newSource[i]);
if (index > -1)
newSource.splice(index, 1);
};
};
};
//update source
field.data('bs.tokenfield').$input.autocomplete({source: newSource})
})
эта функция вызывается после создания или удаления маркера для обновления списка. Он использует JSON.stringify () для сравнения объектов и выполняет сравнение для строковых объектов и для {value: "foo", label: "bar"} исходных объектов.
@Javier ваше решение работает хорошо, но иногда он становится багги и добавить в два раза токен! У тебя есть идея для такого поведения?
PS после просмотра документации я нашел решение. Необходима обработка обоих событий. Потому что события запускаются до и после создания/редактирования / удаления токенов.
поэтому вам нужно это, чтобы предотвратить добавление (перед созданием события)
$('#tokenfield').on('tokenfield:createtoken', function (event) {
var existingTokens = $(this).tokenfield('getTokens');
//check the capitalized version
event.attrs.value = capitalizeFirstLetter(event.attrs.value);
$.each(existingTokens, function(index, token) {
if (token.value === event.attrs.value) {
event.preventDefault();
return false;
}
});
});
и этот другой тоже, как вы предложили, для исходного списка (после создания событие)
$('#tokenfield').on('tokenfield:createdtoken tokenfield:removedtoken', function (event) {
var field = $(this);
var currentTokens = field.tokenfield('getTokens').map(function(i){return i.value});
var originalSource = field.data('bs.tokenfield').options.autocomplete.source;
var newSource = [];
for (var i = 0; i<originalSource.length; i++) {
if(currentTokens.indexOf(originalSource[i])==-1){
newSource.push(originalSource[i]);
}
};
//update source
field.data('bs.tokenfield').$input.autocomplete({source: newSource});
//empty the input field
$(".tokenfield.form-control").find("input.token-input").val("");
});
примечание: Я изменил " цикл проверки "(double for был переполнен) и добавил чек, чтобы избежать" капитализированного " соответствия, на всякий случай, если вам это нужно.
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
}
$('.tokenfield').on('tokenfield:createtoken', function (event) {
var existingTokens = $(this).tokenfield('getTokens');
$.each(existingTokens, function(index, token) {
if (token.value === event.attrs.value)
event.preventDefault();
});
});