2

我有多个输入字段可以使用 jQuery UI 的自动完成插件自动完成。每个输入都有一个对应的隐藏输入(例如,用户名与用户 ID)。在更改处理程序中,我正在设置隐藏字段的值。这完全符合预期。

当我想让 Return 键 + 鼠标单击自动选择下一个字段时,麻烦就来了。如果我不手动触发更改事件,则更改事件ui.item为空。如果我手动触发它,它会触发第二个带有 null 的更改事件ui.item

我可以在更改中添加一个守卫以防止出现 null ui.item,但这会阻止我清除之前填写的字段。

简而言之——按 Tab、Enter 或鼠标单击应该将文本输入的值设置为用户名,将隐藏的输入设置为用户 ID,并聚焦下一个文本输入。

这是一个带有内联注释的 JSFiddle,用于在上下文中说明/解释问题:http: //jsfiddle.net/shipstar/Jvfx3/4/

谢谢!

4

2 回答 2

1

将焦点逻辑移到关闭事件中,将值更新器移到选择事件中

http://jsfiddle.net/Jvfx3/6/

select: function (event, ui){
    var $userIdField = $(this).siblings(".user-id");
    var userId = ui.item ? ui.item.userId : '';
    $userIdField.val(userId);

    $(this).siblings('label').find('span').text(userId);
},
close: function(event, ui){
    if (!event.keyCode || event.keyCode === 13){
        $(this).parents('form').find('.user-name').filter(function (){
            return $(this).val() === '';
        }).first().focus();
    }
}
于 2013-07-30T20:51:10.180 回答
0

不确定您是否仍然遇到此问题,但我遇到的困难与您完全相同。在 JS 和 jQuery 方面,我实际上仍然是新手,所以可能还有其他更好、更简洁的方法可以做到这一点,但我不知道它们是什么,我设法让它在我的代码中工作,所以希望它适用于您或其他任何有此问题的人。

我扩展了@Jacob_Kralls 解决方案,并尝试解决无法删除先前选择的条目的问题。由于 ui.item 在设置焦点后返回 null,我添加了第二个隐藏字段来存储所选值的副本,然后您可以与复制的值字段进行比较,而不是检查大型或远程数据集。

这是小提琴:http: //jsfiddle.net/Jvfx3/11/

带有新 checkVal 字段的 Html 片段:

 <div>
  <input type="hidden" class="user-id" id="h1" />
  <input type="hidden" class="user-name-checkVal" id="cv1" />
  <input type="text"   class="user-name" id="t1" />
  <label>User ID is: <span>undefined</span></label>
 </div>

Javascript 片段:

在 select 事件中,将 checkVal 字段设置为等于所选值。

select: function (event, ui) {
  $(this).siblings(".user-id").val(ui.item.userId);
  $(this).siblings(".user-name-checkVal").val(ui.item.value);
  $(this).siblings('label').find('span').text(ui.item.userId);
},    

在更改事件中将用户名值与 checkVal 进行比较,删除值时允许为空用户名。

change: function (event, ui) {
  var username = $(this).val();
  var checkVal = $(this).siblings(".user-name-checkVal").val();
  if (username == '') {
     //username has changed, and now its null. value has been deleted.
     // clear everything set when value was selected.

     $(this).val('');
     $(this).siblings(".user-name-checkVal").val('');
     $(this).siblings(".user-id").val('undefined');
     $(this).siblings('label').find('span').text('undefined');

   } else if (username != checkVal) {
     //username was not selected from list. reset everything set by select.
     $(this).siblings(".user-name-checkVal").val('');
     $(this).siblings(".user-id").val('');
     $(this).siblings('label').find('span').text('undefined');

     //user-name is invalid, alert user of the error.
     alert('Invalid username. choose from list.');

     //since the value was entered, and not selected, keep focus here.
     $(this).val('');
     $(this).focus();
   }
},

在关闭事件上,再次比较用户名和 checkVal,如果它们匹配,则仅将焦点设置到列表中的下一项。(这在 chrome 中有效,但在 Firefox 中,光标仍然出现在下一项中,不知道为什么)

 close: function (event, ui) {
    if (!event.keyCode || event.keyCode === 13) {
       var username = $(this).val();
       var checkVal = $(this).siblings(".user-name-checkVal").val();
       if (username == checkVal) {
          $(this).parents('form').find('.user-name')
                 .filter(function () { return $(this).val() === ''; })
                 .first().focus();
        }

     }
}
于 2013-10-01T22:43:35.187 回答