我正在使用Select2(版本3.4.0)来填充标记列表.标签通过ajax调用与现有标签匹配,我createSearchChoice用来创建新标签.代码到目前为止工作,看起来像这样:
$(mytags).select2({
multiple: true,
placeholder: "Please enter tags",
tokenSeparators: [ "," ],
ajax: {
multiple: true,
url: myurl,
dataType: "json",
data: function(term, page) {
return {
q: term
};
},
results: function(data, page) {
return data;
}
},
createSearchChoice: function(term) {
return {
id: term,
text: term + ' (new)'
};
},
});
Run Code Online (Sandbox Code Playgroud)
所有漂亮的标准,除了注意附加(new)在createSearchChoice.我需要用户知道这不是一个预先存在的标签.
它按预期工作:如果我开始输入"new-tag",我会在列表顶部显示"new-tag(new)"标签,如果我选择它,则标签列表包含"new-tag(new ),"如预期的那样.如果标签已存在,则Select2检测到匹配,并且不会创建"(新)"选项.按返回或单击匹配按预期工作.
当我tokenSeparators在匹配时输入逗号(我的单个条目)时会出现问题.Select2关闭该标记,并将标记添加到列表中,但附加了"(new)"标签,即它使用了返回值,createSeachChoice即使它没有.
这是Select2中的错误,还是我错误地使用它(我应该怎么做)?
Jon*_*Jon 16
我不确定这是不是一个错误 - 无论如何,目前GitHub问题跟踪器上没有涉及此行为的公开问题.
你可以自己修复行为.这个想法是createSearchChoice回调必须能够判断是否term引用了搜索结果.但是createSearchChoice没有直接访问搜索结果,那么我们如何才能实现呢?好吧,通过从results回调内部保存最新一批搜索结果.
var lastResults = [];
$(...).select2({
ajax: {
multiple: true,
url: "/echo/json/",
dataType: "json",
type: "POST",
data: function (term, page) {
return {
json: JSON.stringify({results: [{id: "foo", text:"foo"},{id:"bar", text:"bar"}]}),
q: term
};
},
results: function (data, page) {
lastResults = data.results;
return data;
}
},
createSearchChoice: function (term) {
if(lastResults.some(function(r) { return r.text == term })) {
return { id: term, text: term };
}
else {
return { id: term, text: term + " (new)" };
}
}
});
Run Code Online (Sandbox Code Playgroud)
这段代码使用Array.some所以你需要比IE8(这是select2最低要求)更好的东西来运行它,但当然可以模拟行为.
然而,美中不足的是:只有在已经收到与当前搜索词相对应的搜索结果时,此代码才能正常工作.
这应该是显而易见的:如果您输入非常快并创建一个与现有标签相对应的搜索词,但在包含该标签的搜索结果到达之前点击逗号,createSearchChoice则将测试该标签在先前收到的搜索结果中的存在.如果这些结果不包含标记,则标记将显示为"新",即使它不是.
不幸的是,我不相信你可以采取任何措施来防止这种情况发生.
我认为最好在服务器端工作,而不是推测结果.
如果服务器找不到标记,则使用新标记返回json应答
{"more":false,"results":[{"id":"whatever","text":"new-tag (new)"}]}
Run Code Online (Sandbox Code Playgroud)