如何使用 Bootstrap Tokenfield 防止重复使用 Jquery Ui 自动完成
How to prevent duplicate with Bootstrap Tokenfield When using Jquery Ui Autocomplete
我正在尝试实施 Bootstrap Tokenfield with Jquery Ui autocomplete
到目前为止,我能够做到这一点,除了我无法防止输入字段中的重复,所以,不幸的是,我的用户可以选择相同的值两次。
在我的搜索中,我发现 Bootstrap Tokenfield 有一种 preventing duplicate 的方式。但是我不知道如何应用到我的代码,因为在我看来它与 Twitter typeahead 而不是 Jquery Ui.
如何使用 Jquery Ui 自动完成来防止与 Bootstrap TokenField 重复?
这是我的 Bootstrap 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();
});
});
我想你已经完成了,剩下要做的就是更换 class
所以在第一个代码之后,而不是第二个代码写
$('.tokenfield').on('tokenfield:createtoken', function (event) {
var existingTokens = $(this).tokenfield('getTokens');
$.each(existingTokens, function(index, token) {
if (token.value === event.attrs.value)
event.preventDefault();
});
});
这里的不同之处在于必须应用您的 class,它适用于 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 看了文档后我找到了解决办法。这两个事件处理都是需要的。因为事件在 creation/edit/remove 个令牌之前和之后触发。
所以你需要这个来防止添加(在创建事件之前)
$('#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("");
});
注意:我更改了 "check loop",(double for 太过分了),并添加了一个检查以避免 "capitalized" 匹配,以防万一你需要它。
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
}
我正在尝试实施 Bootstrap Tokenfield with Jquery Ui autocomplete 到目前为止,我能够做到这一点,除了我无法防止输入字段中的重复,所以,不幸的是,我的用户可以选择相同的值两次。
在我的搜索中,我发现 Bootstrap Tokenfield 有一种 preventing duplicate 的方式。但是我不知道如何应用到我的代码,因为在我看来它与 Twitter typeahead 而不是 Jquery Ui.
如何使用 Jquery Ui 自动完成来防止与 Bootstrap TokenField 重复?
这是我的 Bootstrap 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();
});
});
我想你已经完成了,剩下要做的就是更换 class
所以在第一个代码之后,而不是第二个代码写
$('.tokenfield').on('tokenfield:createtoken', function (event) {
var existingTokens = $(this).tokenfield('getTokens');
$.each(existingTokens, function(index, token) {
if (token.value === event.attrs.value)
event.preventDefault();
});
});
这里的不同之处在于必须应用您的 class,它适用于 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 看了文档后我找到了解决办法。这两个事件处理都是需要的。因为事件在 creation/edit/remove 个令牌之前和之后触发。
所以你需要这个来防止添加(在创建事件之前)
$('#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("");
});
注意:我更改了 "check loop",(double for 太过分了),并添加了一个检查以避免 "capitalized" 匹配,以防万一你需要它。
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
}