具有混合文本/ ID搜索的jQuery UI自动完成
我在为jQuery的自动完成小部件工作方面遇到了很多麻烦。 我正在使用服务器中的键/值对列表。
我有以下要求:
如果用户从窗口小部件中选择一个值,我想将ID传递给服务器。
如果用户没有选择值并输入原始文本,或者修改已经选择的值,我希望清除ID字段,只需要将原始文本发送到服务器。
假设someAjaxFunction
返回自动完成小部件所需的对象数组: {label:label, value:key}
。
最初我像这样设置自动完成小部件:
$(input).autocomplete({ source: sourceFunction, minLength: 1 });
即使将鼠标hover在其中一个项目上,更改选择也会将$(输入)引用的文本框中的文本更改为基础键,而不是标签。 从用户交互的角度来看,这是非常不受欢迎的 – 事实上,我正在调查这一点的原因是因为我正在构建的网站的用户一直对他们输入的文本感到困惑,似乎变成了随机数!
我在文本框下添加了一个隐藏字段,并实现了select()和focus()事件,以便隐藏ID,如下所示:
$(input).autocomplete({ source: sourceFunction, minLength: 1 focus: function(event, ui) { $(idField).val(ui.item.value); $(this).val(ui.item.label); return false; }, select: function(event, ui) { $(idField).val(ui.item.value); $(this).val(ui.item.label); return false; }, minLength: 1 });
当用户坚持使用自动完成下拉列表提供的脚本时,这很有效。 该ID被隐藏并正确提交给服务器。 不幸的是,如果用户想要在框中输入一些自由格式文本并根据该值进行搜索,则不会重置ID字段,并且先前选择的ID将提交给服务器。 这也很令人困惑。
jQuery UI自动完成文档列出了change
事件,并声明ui
参数的item
属性将设置为所选项。 我想我可以在按键上重置隐藏的id字段,并在更改自动完成时重新填充ID。 不幸的是,除了按键事件捕获一大堆不应该重置ID的按键之外,上述select
事件中的return false
语句是管理文本框中文本所必需的,它可以防止change
事件具有ui。项目正确分配。
所以现在我被卡住了 – 我真的不知道还有什么我可以尝试制作它看起来应该默认支持的小部件支持function。 这个过程要么比它应该更复杂,要么我错过了一些非常明显的东西。 我已经完成了所有可用的事件和所有示例,然后空手而归。 实际上,即使是jQuery UI页面上的“自定义数据和显示”示例也会遇到此问题。
我可以在服务器端添加一些黑客来覆盖这个,但我真的更愿意能够在客户端级别执行此操作。
我也更喜欢坚持使用jQuery UI自动完成小部件而不是切换到另一个小部件。
我正在做自动完成的方法是创建一个包含输入的容器div。 当我选择一个元素时,我将一个包含span的链接添加到容器中,然后隐藏输入框。
链接和跨度的样式使其看起来像一个带有X的按钮,并具有一个单击事件处理程序以从DOM中删除条目,清除隐藏字段,并在单击时重新显示输入框。 所以当选择一个项目时:
并且当未选择项目时:
这样,您可能被迫选择一个项目,或者您输入自由格式文本。 在后端,如果带有键’myvalue’的请求参数为空,那么您更愿意使用键’myautocomplete’查看请求参数。
当我假设您设置了以下字段时:
你需要初始化js(它适用于jQuery 1.5.2):
$(document).ready(function() { $('.autocomplete-reference').each(function () { $(this).keydown(function(e){ /* * this will reset hidden id reference on each visible field manual change * we have to bind it on keydown because we want to recognize event of submiting form by enter after autocomplete set */ if (e.keyCode != 13) { $(this).siblings('input[type=hidden]').each(function () { $(this).val(''); }); } }); $(this).autocomplete({ minLength: 1, /* you can set appending of autocomplete menu into some container to set css contextually appendTo: '#someElem',*/ source: sourceFunction, search:function (event, ui) { //TODO ...spinner init... }, open:function (event, ui) { /* you can grab autocomplete menu widget by this to manipulate some recognizing id, etc.. * $(this).autocomplete('widget') */ //TODO ..stop spinner ... $(this).keydown(function(e){ /* this is important for live reference updates while arrow keys changes */ if (e.keyCode == 37 || e.keyCode == 39) { $($(this).data('autocomplete').menu.active).find('a').trigger('click'); } }); }, focus: function(event, ui) { /* here we'll map our data object onto both fields */ $(this).val(ui.item.label); $(this).siblings('input[type=hidden]').each(function () { $(this).val(ui.item.key); }); }, select: function(event, ui) { /* here we'll map our data object onto both fields */ $(this).val(ui.item.label); $(this).siblings('input[type=hidden]').each(function () { $(this).val(ui.item.key); }); }, close: function(event, ui) { //TODO ..stop spinner ... } }); }); });
有一些服务器端validation非常好,它可以将exact:visible字段值转换为快速键入人员的引用。
虽然这是一个老问题,但我的方法可以提供帮助。
在.change
事件上,您可以使用循环从源列表中使用值来搜索文本框值。
转到更多详细信息:这是在Ajax源列表中,但锻炼类似。 在Jquery AutoComplete Ui中搜索文本
这件事困扰了我很多次,最终我现在明白了:)
您可以使用event.preventDefault
通过ui.item.label或ui.item.value收集所选值,并获取所需的值并将其设置为相同的文本框。
var idNameCombo = ui.item.label; event.preventDefault(); $("#mID").val(idNameCombo.split(",")[0].trim());