jQuery UI自动完成小部件的搜索配置

65

我正在研究使用jQuery UI自动完成小部件来实现按名字查找用户,可以是名字的第一个字母或最后一个字母。默认情况下,自动完成会根据字符序列查找单词,而不管其在单词中出现的位置。因此,如果您有以下数据:javascript、asp、haskell,并且您键入'as',则会返回所有三个结果。 我想让它只匹配单词的开头。所以在上面的例子中,您只会得到'asp' 。 有没有办法配置自动完成小部件来实现这一点?

最终,最好能够像Gmail一样,根据名字的开头匹配或末尾。

注意:我正在尝试找出一种使用特定的jQuery UI小部件来实现这一点的方法。由于我的项目已经在使用jQuery UI,因此我计划坚持使用它,并尝试不向我的Web应用程序添加其他库。


Henchman为Gmail一样的搜索提供了解决方案。https://dev59.com/k3E95IYBdhLWcg3wRLwt#2405646 - dev.e.loper
6个回答

129
在jQuery UI v1.8rc3中,自动完成小部件接受一个source选项,可以是字符串、数组或回调函数。 如果是一个字符串,自动完成将在该URL上执行GET以获取选项/建议。 如果是数组,则自动完成会搜索任何位置的术语中是否存在键入的字符,正如您所指出的那样。 最终的变体是您想要的-回调函数。
来自自动完成文档:
第三个变体,回调提供了最大的灵活性,并且可用于将任何数据源连接到自动完成。 回调获取两个参数:
•一个request对象,带有一个名为“term”的属性,该属性引用当前在文本输入中的值。 例如,当用户在设置为进行自动完成的城市字段中输入“new yo”时,request.term将保持“new yo”。
•response函数,一个回调函数,它期望一个单一的参数包含要向用户建议的数据。 这些数据应基于提供的术语进行过滤,并且必须是允许简单本地数据的格式的数组:具有标签/值/两个属性的String-Array或Object-Array。
示例代码:
var wordlist= [ "about", "above", "across", "after", "against",
                "along", "among", "around", "at", "before", 
                "behind", "below", "beneath", "beside", "between", 
                "beyond", "but", "by", "despite", "down", "during", 
                "except", "for", "from", "in", "inside", "into", 
                "like", "near", "of", "off", "on", "onto", "out", 
                "outside", "over", "past", "since", "through", 
                "throughout", "till", "to", "toward", "under", 
                "underneath", "until", "up", "upon", "with", 
                "within", "without"] ; 

$("#input1").autocomplete({
    // The source option can be an array of terms.  In this case, if
    // the typed characters appear in any position in a term, then the
    // term is included in the autocomplete list.
    // The source option can also be a function that performs the search,
    // and calls a response function with the matched entries.
    source: function(req, responseFn) {
        var re = $.ui.autocomplete.escapeRegex(req.term);
        var matcher = new RegExp( "^" + re, "i" );
        var a = $.grep( wordlist, function(item,index){
            return matcher.test(item);
        });
        responseFn( a );
    }
});

一些关键点:
- 调用$.ui.autocomplete.escapeRegex(req.term);来转义搜索词,这样用户输入的文本中任何在正则表达式中有意义的术语都将被视为纯文本。例如,句点(.)在正则表达式中是有意义的。我通过阅读自动完成源代码学习了这个escapeRegex函数。 - 带有new Regexp()的行指定以^(Circumflex)开头的正则表达式,这意味着只有在数组中的术语以所键入的字符开头时才会匹配,这正是您想要的。它还使用“i”选项,这意味着进行不区分大小写的匹配。 - $.grep()实用程序只对提供的数组中的每个术语调用提供的函数。在这种情况下,该函数仅使用正则表达式来查看数组中的项是否与所键入的内容匹配。 - 最后,responseFn()使用搜索结果调用。
工作演示:http://jsbin.com/ezifi 它的样子是这样的:

alt text

只是提醒一下:我认为自动完成功能的文档目前还比较不成熟。我没有找到能够做到这一点的示例,也没有找到哪些 .css 文件是必需的或将使用哪些 .css 类。我是通过检查代码来学习所有这些知识的。
另请参阅如何自定义格式化Autocomplete插件结果?

3
+1 很棒的回答!我也在检查代码并试图弄清楚 escapeRegex 具体是用来做什么的,你的帖子完美地解释了它。 - Tauren
很棒的答案。我同意文档还不够成熟。这正是我在寻找的。 - Tim Banks
1
非常感谢!我使用了可变数量的自动完成(每行一个,带有嵌套表格),但开箱即用的速度非常慢,即使使用JS对象来本地缓存我的数据(我认为数据被复制到每个表格中)。这极大地加快了我的应用程序速度,并且在此基础上使用缓存解决方案(避免在页面加载后处理相同的查询两次),我对结果非常满意 :) - Yablargo
1
致所有人:关于jQuery UI文档中“缺乏成熟度”的补充说明。jQuery UI文档项目负责人Scott Gonzalez友好地给我发邮件,告诉我新的jQuery UI文档网站内容现在已经上传到GitHub上了,https://github.com/jquery/api.jqueryui.com 。任何人都可以自由地fork并发送pull请求! - Cheeso
同时,我的变量看起来像这样 [{"name":"SIK1B","organism":"Homo sapiens"},{"name":"Nep2","organism":"Drosophila melanogaster"}] - Brian Wiley
显示剩余2条评论

6

感谢Cheeso介绍jsbin.com,

我扩展了您的代码,支持名字和姓氏的匹配。

  $("#input1").autocomplete({
      source: function(req, responseFn) {
          addMessage("search on: '" + req.term + "'<br/>");

          var matches = new Array();
          var needle = req.term.toLowerCase();

          var len = wordlist.length;
          for(i = 0; i < len; ++i)
          {
              var haystack = wordlist[i].toLowerCase();
              if(haystack.indexOf(needle) == 0 ||
                 haystack.indexOf(" " + needle) != -1)
              {
                  matches.push(wordlist[i]);
              }
          }

          addMessage("Result: " + matches.length + " items<br/>");
          responseFn( matches );
      }
  });

示例: http://jsbin.com/ufimu3/

输入 'an' 或 're'


6

我使用的是devbridge的自动完成插件。http://www.devbridge.com/projects/autocomplete/jquery/

它只匹配开头字符。

alt text

关于基于名字匹配,您只需要提供一个包含名字和姓氏的查找列表。

示例用法:

  var wordlist = [
      'January', 'February', 'March', 'April', 'May', 'June',
      'July', 'August', 'September', 'October', 'November',
      'December' ]; 

      var acOptions = {
          minChars:2,
          delimiter: /(,|;)\s*/, // regex or character
          maxHeight:400,
          width:300,
          zIndex: 9999,
          deferRequestBy: 10, // miliseconds

          // callback function:
          onSelect: function(value, data){
              //$('#input1').autocomplete(acOptions);
              if (typeof data == "undefined") {
                  alert('You selected: ' + value );
              }else {
                  alert('You selected: ' + value + ', ' + data);
              }
          },

          // local autosuggest options:
          lookup: wordlist
      };

您传递给初始化自动完成控件的lookup选项可以是列表或对象。上面展示了一个简单的列表。如果您想要一些数据附加到返回的建议中,那么将lookup选项设置为对象,如下所示:

var lookuplist = {
    suggestions:   [ "Jan", "Feb", "Mar", "Apr", "May" ],
    data :         [ 31, 28, 31, 30, 31, ]
};

Cheeso,感谢您的建议,非常有帮助。由于我已经在我的项目中使用了jQueryUI插件,所以我计划坚持使用它,并尝试不向我的Web应用程序添加其他插件。 - dev.e.loper
有道理。在这种情况下,您可以考虑对jQuery UI源代码进行一次性修改,以满足您的要求。我曾经这样做来修复我遇到的几个错误,在尚未发布的版本中已经修复了。这对您也可能有意义。 - Cheeso
PS:我没有意识到自动完成插件是在jQueryUI v1.8中首次包含的。我使用的是v1.7.2。 - Cheeso

3

如果您想在字符串中搜索每个单词的开头,一种更优雅的解决方案是采用cheeso的正则表达式单词边界特殊字符:

var matcher = new RegExp( "\\b" + re, "i" );

示例:http://jsbin.com/utojoh/2(尝试搜索“bl”)


0

另一个jQuery自动完成插件,它可以选择仅在每个项目开头进行搜索(该选项为matchContains=false,我认为这也是默认设置)。

鉴于jQuery UI插件中没有此选项,我猜想您必须使用不同的插件或重新编写您现在正在使用的插件。


不,他不需要重写jQueryUI来实现自动完成。有一个选项可以满足他的需求。请查看我的回答。https://dev59.com/k3E95IYBdhLWcg3wRLwt#2405109 - Cheeso
啊,太棒了。你说它是在jQuery UI 1.8中的吗?那个版本已经发布了吗? - Paul D. Waite
据我所知,jQueryUI v1.8被列为rc3。“发布候选版#3”。通常情况下,RC是一个相当稳定的版本,非常接近最终版本。但这只是通常情况下。我不清楚jQuery的发布评级惯例。 - Cheeso

0
你从哪里获取数据来填充自动完成?是从数据库中获取的吗?如果是这样,你可以在查询中进行所需操作,并仅返回与每个单词(名字的首字母或尾字母)开头匹配的结果。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接