65

我正在研究使用jQuery UI 自动完成小部件来实现按名字或姓氏查找用户。默认情况下,自动完成似乎是按字符序列查找单词,无论它出现在单词中。因此,如果您有以下数据:javascript, asp, haskell并且您输入'as'您将获得所有三个数据。我希望它只匹配单词的开头。所以在上面的例子中你只得到'asp'. 有没有办法配置自动完成小部件来做到这一点?

最终,最好以名字或姓氏的开头来匹配,就像在 Gmail 中一样。

注意:我正在尝试找出一种专门使用 jQuery UI 小部件的方法。因为我已经在我的项目中使用了 jQuery UI,所以我打算坚持使用它并尽量不向我的 Web 应用程序添加额外的库。

4

6 回答 6

128

在 jQuery UI v1.8rc3 中,自动完成小部件接受一个选项,它可以是字符串、数组或回调函数。如果它是一个字符串,自动完成功能会在该 URL 上执行 GET 以获取选项/建议。如您所指出的,如果是数组,则自动完成会搜索在数组项中的任何位置是否存在键入的字符。最后一个变体就是你想要的——回调函数。

从自动完成文档中:

第三种变体,回调,提供了最大的灵活性,可用于将任何数据源连接到自动完成。回调有两个参数:

• 一个request对象,具有一个名为“term”的属性,它指的是文本输入中当前的值。例如,当用户在设置为自动完成的城市字段中输入“new yo”时,request.term将保留“new yo”。
• 一个response函数,一个回调函数,它期望单个参数包含要向用户建议的数据。此数据应根据提供的术语进行过滤,并且必须是简单本地数据所允许格式的数组:字符串数组或对象数组,带有标签/值/两个属性。

示例代码:

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); That的调用会转义搜索词,以便用户键入的文本中的任何正则表达式有意义的词都被视为纯文本。例如,点 (.) 对正则表达式有意义。我通过阅读自动完成源代码了解了这个 escapeRegex 函数。
  • new Regexp(). 它指定了一个以 ^ (Circumflex) 开头的正则表达式,这意味着只有当键入的字符出现在数组中术语的开头时,它才会匹配,这正是您想要的。它还使用“i”选项,这意味着不区分大小写的匹配。
  • $.grep()实用程序只是在提供的数组中的每个术语上调用提供的函数。本例中的函数仅使用正则表达式来查看数组中的术语是否与键入的内容匹配。
  • 最后,使用搜索结果调用 responseFn()。

工作演示:http: //jsbin.com/ezifi

它看起来像什么:

替代文字

请注意:我发现关于自动完成的文档目前还很不成熟。我没有找到这样做的示例,也找不到关于哪些 .css 文件是必要的或将使用哪些 .css 类的工作文档。我从检查代码中学到了这一切。

另请参阅,如何自定义格式自动完成插件结果?

于 2010-03-08T21:59:14.587 回答
6

我使用 devbridge 的自动完成功能。 http://www.devbridge.com/projects/autocomplete/jquery/

它只匹配开头的字符。

替代文字

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

示例用法:

  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, ]
};
于 2010-03-04T21:02:28.863 回答
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”

于 2010-03-08T23:45:27.733 回答
3

如果要搜索字符串中每个单词的开头,更优雅的解决方案是使用 cheeso's,但只需使用正则表达式单词边界特殊字符:

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

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

于 2011-08-16T17:07:52.327 回答
0

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

鉴于 jQuery UI 插件中没有这样的选项,我猜你要么必须使用不同的插件,要么重写你现在使用的插件。

于 2010-03-08T15:22:18.360 回答
0

您从哪里获取数据以填充自动完成功能?它来自数据库吗?如果是这样,您可以在查询中执行您想要的操作,并且只返回与每个单词开头匹配的结果(名字/姓氏)

于 2010-03-08T16:29:23.180 回答