我在让 jQuery 的自动完成小部件为我工作时遇到了很多麻烦。我正在使用服务器中的键/值对列表。
我有以下要求:
如果用户从小部件中选择一个值,我想将 ID 传递到服务器。
如果用户未选择值并输入原始文本,或修改已选择的值,我希望清除 ID 字段,仅将原始文本发送到服务器。
假设 someAjaxFunction
返回自动完成小部件所需的对象数组:{label:label, value:key}
。
最初我像这样设置自动完成小部件:
$(input).autocomplete({
source: sourceFunction,
minLength: 1
});
即使将鼠标悬停在其中一项上来更改选择也会将 $(input) 引用的文本框中的文本更改为基础键,而不是标签。从用户交互的角度来看,这是非常不受欢迎的 - 事实上,我调查这个问题的真正原因是因为我正在构建的网站的用户一直对他们输入的文本似乎变成随机数字感到困惑!
我在文本框下添加了一个隐藏字段,并实现了 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.item。
所以现在我陷入了困境 - 我真的不知道我还能尝试什么来使小部件支持默认情况下应该支持的功能。要么这个过程比应有的复杂得多,要么我错过了一些非常明显的东西。我已经挑选了所有可用的事件和所有示例,但却空手而归。事实上,即使是 jQuery UI 页面上的“自定义数据和显示”示例也存在这个问题。
我可以在服务器端添加一些技巧来解决这个问题,但我真的更希望能够在客户端级别执行此操作。
我也更愿意坚持使用 jQuery UI 自动完成小部件,而不是切换到另一个小部件。
最佳答案
我执行自动完成的方式是创建一个包含输入的容器 div。当我选择一个元素时,我将包含跨度的链接添加到容器中,并隐藏输入框。
链接和跨度的样式使其看起来像一个带有 X 的按钮,并具有一个单击事件处理程序,用于从 DOM 中删除条目、清除隐藏字段并在单击时重新显示输入框。因此,当选择一个项目时:
<div class="container">
<a href="#"><span>Selected Item</span></a>
<input id="myautocomplete" type="text" />
<input type="hidden" name="myvalue" value="1" />
</div>
当未选择某个项目时:
<div class="container">
<input id="myautocomplete" name="myautocomplete" type="text" />
<input id="myvalue" name="myvalue" type="hidden" value="" />
</div>
这样,您要么被迫选择一个项目,要么输入自由格式的文本。在后端,如果带有“myvalue”键的请求参数为空,那么您宁愿查看带有“myautocomplete”键的请求参数。
关于jQuery UI 自动完成与混合文本/ID 搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3299839/