【问题标题】:jQuery UI Autocomplete -- make click/enter move to next fieldjQuery UI 自动完成——使点击/输入移动到下一个字段
【发布时间】:2013-07-30 23:03:11
【问题描述】:

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

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

我可以在更改中添加保护以防止出现空 ui.item,但这会阻止我清除之前填写的字段。

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

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

谢谢!

【问题讨论】:

  • 另一种方法是使用自动完成的原始源数组来查找相关值。这对于小数据集来说很好(虽然很笨拙),但对于大数据集似乎是不可取的。
  • 另一个 hacky 解决方案是添加一个空白条目并将 minLength 设置为 0。这在视觉上很尴尬,并且当我切换到服务器端数据源时性能会很差。

标签: jquery autocomplete jquery-ui-autocomplete


【解决方案1】:

将焦点逻辑移到close event 中,将值更新器移到select event 中。

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();
    }
}

【讨论】:

  • 这修复了一个无意的副作用,但我认为核心问题仍然存在——两个事件正在触发。我可以在 _trigger 上设置超时以确保正确的顺序,但这仍然感觉像是一个 hack。
  • re: fiddle #6 -- 这修复了双重触发,但失去了删除以前选择的条目的能力,因为选择事件仅在您明确选择源数据中的某些内容时触发。 #whackamole
【解决方案2】:

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

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

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

带有新 checkVal 字段的 HTML sn-p:

 <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 sn-ps:

在 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();
        }

     }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-22
    • 2011-11-16
    相关资源
    最近更新 更多