【问题标题】:jQuery autocomplete: undefined value pressing the UP arrow keyjQuery自动完成:按向上箭头键未定义的值
【发布时间】:2019-03-02 12:51:41
【问题描述】:

我正在开发一个应用程序,我需要使用jQuery 提供的autocomplete 函数进行输入。一切都很好,直到我在实际添加选项的<ul> 中添加更多元素。

我需要的是一些“上下文帮助”,我可以在其中向用户展示他可以在那里输入的一些基本查询。

在您多次按向上箭头键之前,它们会出现并且似乎有效。如果您在第一个元素上并按up 箭头键,则焦点将移至输入。如果我再次按up 箭头键,则会出现错误并且我的应用程序崩溃:

uncaught TypeError: Cannot read property 'value' of undefined
    at $.(fiddle.jshell.net/_display/anonymous function).(anonymous function).menufocus (https://code.jquery.com/ui/1.12.1/jquery-ui.js:5831:25)
    at HTMLUListElement.handlerProxy (jquery-ui.js:606)
........

down 箭头键工作正常。 您可以查看jsfiddle here 或以下地址。 如何复制错误:

  • 关注输入框,写COM;将出现一个虚拟的自动完成功能

  • 使用down箭头键向下移动1-2个元素;然后,使用up 箭头键移回第一个元素;

  • up箭头键将焦点移到输入框上

  • 再次按up箭头键

var tags = ["COMMAND_1", "COMMAND_2", "COMMAND_3", "COMMAND_4"];
$("#autocomplete").autocomplete({
  open: function(e, ui) {
    var autocompleteElement = $('.ui-autocomplete');
    contextualItems = ["COMMAND_1 {item}", "COMMAND_2 {item}", "COMMAND_3 {item}", "COMMAND_4 [{item_1}, {item_2}]"]

    autocompleteElement.append('<li class="ch">Contextual Help</li>');

    for (var i = 0; i < contextualItems.length; i++) {
      autocompleteElement.append('<li class="ui-autocomplete-category" style="background-color: #EEE; padding-top: 5px">' + contextualItems[i] + '</li>');
      console.log(contextualItems[i]);
    }

  },
  source: function(request, response) {
    var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex(request.term), "i");
    response($.grep(tags, function(item) {
      return matcher.test(item);
    }));
  }
});
.ch {
  background-color: #EEE;
  border-top: solid 1px grey;
  padding-top: 5px;
  text-align: center;
  font-weight: bold
}
<!doctype html>
<html lang="en">

  <head>
    <meta charset="utf-8">
    <title>autocomplete demo</title>
    <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/smoothness/jquery-ui.css">
    <script src="//code.jquery.com/jquery-1.12.4.js"></script>
    <script src="//code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
  </head>

  <body>

    <label for="autocomplete">Select a programming language: </label>
    <input id="autocomplete">

  </body>

</html>

我尝试更改 div 中的上下文帮助,我尝试使用类别,但没有成功。你能给我一个提示或想法,我可以如何解决这个问题吗? 谢谢!

【问题讨论】:

  • 小提琴在 Firefox 中对我来说很好用,但堆栈 sn-p 确实显示了错误。诡异的。编辑:对,我没有检查控制台
  • @ChrisG 是的,小提琴似乎“工作”,但错误就在那里。因此,我的真实应用程序完全崩溃了。
  • 自动完成插件使用.data() 将信息与它在完成列表中创建的每个&lt;li&gt; 关联起来。问题是您在类别中添加了自己的&lt;li&gt;,但它没有插件期望的数据。
  • here 是一个显示如何将类别添加到自动完成的问题
  • @Barmar 您链接的问题中的选定答案具有与 OP 描述的完全相同的错误。请链接一个显示问题已得到修复的小提琴。

标签: javascript jquery html css autocomplete


【解决方案1】:

正如 cmets 中所述,我怀疑您是否应该手动更改 .ui-autocomplete 的内容。

您可以做的是在下拉列表之外添加上下文帮助元素,并将其动态定位在focus(或任何其他事件,取决于):

var tags = ["COMMAND_1", "COMMAND_2", "COMMAND_3", "COMMAND_4"];
$("#autocomplete").autocomplete({
  source: function(request, response) {
    var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex(request.term), "i");
    response($.grep(tags, function(item) {
      return matcher.test(item);
    }));
  },

  focus: function(event, ui) {
    $('[data-context-help]')
      .css({
        top: $('.ui-autocomplete').position().top + $('.ui-autocomplete').outerHeight(true),
        left: $('.ui-autocomplete').position().left,
        width: $('.ui-autocomplete').outerWidth(true)
      })
      .text('Help for ' + ui.item.value)
      .show()
  }, 
  
  close: function(event, ui) {
    $('[data-context-help]').hide();
  }
});
.ch {
  background-color: #EEE;
  border-top: solid 1px grey;
  padding-top: 5px;
  text-align: center;
  font-weight: bold;
  position: absolute;
}
<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <title>autocomplete demo</title>
  <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/smoothness/jquery-ui.css">
  <script src="//code.jquery.com/jquery-1.12.4.js"></script>
  <script src="//code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>

<body>

  <label for="autocomplete">Select a programming language: </label>
  <input id="autocomplete">

  <div data-context-help class="ch" style="display:none">Help goes here</div>

</body>

</html>

【讨论】:

  • 我喜欢它!通过一些小的调整,我设法将它实现到我的应用程序中,并且运行良好。谢谢:D
【解决方案2】:

Jquery-UI 的自动完成总是会创建一个带有items 选项的菜单,该选项接受所有子项作为菜单项。不幸的是,它在自动完成类中被硬编码。您可以更改选项以避免选择不是正确项目的元素,但 JQuery 建议不要在创建菜单后更改它。尽管如此,你仍然可以做到,而且它似乎对我有用。要更改自动更正输入后创建的ui-menu 中的items 选项,我做了:

$("#autocomplete ~ .ui-menu").menu("option", "items", "> :not(.ui-autocomplete-category):not(.ch)" );

在我的示例中,我使用了兄弟选择器,以便您可以根据需要将其设置为特定于自动完成 ID(假设每个容器最多只有一个自动完成)。无论您选择ui-menu 的最佳方式是什么,您都应该使用它;这只是一个例子。

var tags = ["COMMAND_1", "COMMAND_2", "COMMAND_3", "COMMAND_4"];
$("#autocomplete").autocomplete({
  open: function(e, ui) {
    var autocompleteElement = $('.ui-autocomplete');
    contextualItems = ["COMMAND_1 {item}", "COMMAND_2 {item}", "COMMAND_3 {item}", "COMMAND_4 [{item_1}, {item_2}]"]

    autocompleteElement.append('<li class="ch">Contextual Help</li>');

    for (var i = 0; i < contextualItems.length; i++) {
      autocompleteElement.append('<li class="ui-autocomplete-category" style="background-color: #EEE; padding-top: 5px">' + contextualItems[i] + '</li>');
      console.log(contextualItems[i]);
    }

  },
  source: function(request, response) {
    var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex(request.term), "i");
    response($.grep(tags, function(item) {
      return matcher.test(item);
    }));
  }
});

$("#autocomplete ~ .ui-menu").menu("option", "items", "> :not(.ui-autocomplete-category):not(.ch)");
.ch {
  background-color: #EEE;
  border-top: solid 1px grey;
  padding-top: 5px;
  text-align: center;
  font-weight: bold
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <title>autocomplete demo</title>
  <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/smoothness/jquery-ui.css">
  <script src="//code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>

<body>

  <label for="autocomplete">Select a programming language: </label>
  <input id="autocomplete">

</body>

</html>

JSFiddle 在:

https://jsfiddle.net/p1y2587a/7/

【讨论】:

  • 如果你做一个堆栈 sn-p 而不是 jsfiddle 就好了。
  • @Barmar 谢谢。我刚刚加了一个。
  • 感谢您的解决方案!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-07
  • 2012-05-13
  • 1970-01-01
  • 2021-08-07
  • 1970-01-01
  • 2017-05-31
相关资源
最近更新 更多