专注于jQuery自动完成结果(不一定是第一个)

我正在努力扩展jQuery自动完成function,以便特定项目默认具有焦点。 开箱即用的function非常好用,但并不完美。 使用autoFocus选项,我可以自动聚焦第一项。

 $( "#input" ).autocomplete({ source: "autocomplete.php", minLength: 1, autoFocus: true }); 

但是,我希望能够更好地控制关注哪个项目。 如果用户键入“eng”并且我的源返回的相关项目是:

  • 美式英语
  • 英式英语
  • 英语
  • 苏格兰英语

我想第三项, 英语 ,默认是焦点(即实际以用户输入开头的项目,即使我想显示其他结果)。 理想情况下,我的源 – autocomplete.php – 将能够指示哪个项目是默认焦点。

有任何想法吗? 我甚至不确定如何开始。

利用open事件,有一种简单的方法可以实现这一目标。 您可以选择默认项目的客户端代码句柄,或者使用您想要选择的项目向下发送一个额外的属性。 我会回顾两个选项:

从客户选择的期限开始的重点建议:

 $("input").autocomplete({ source: /* ... */, open: function (event, ui) { var menu = $(this).data("uiAutocomplete").menu , i = 0 , $items = $('li', menu.element) , item , text , startsWith = new RegExp("^" + this.value, "i"); for (; i < $items.length && !item; i++) { text = $items.eq(i).text(); if (startsWith.test(text)) { item = $items.eq(i); } } if (item) { menu.focus(null, item); } } }); 

基本上这个想法是在自动完成菜单打开时执行以下操作:

  • 构建正则表达式以查找以搜索词开头的单词。
  • 迭代每个菜单项并根据正则表达式测试其文本。 如果我们找到匹配项,请停止迭代并存储该值。
  • 如果我们检索了一个值,请使用菜单上的focus方法突出显示该项目。

示例: http //jsfiddle.net/J5rVP/40/ (尝试搜索英语或S cots英语)

代码使用本地数据源,但它应该与远程源一样好用。


建议的重点从术语开始,在服务器上选择

扩展上面的示例,您可以调整发送数据的方式,以便在每次搜索时,服务器端代码决定选择哪个项目。 您只需在要选择的项目上指定其他属性即可。 例如,您的JSON响应可能如下所示:

 [{"label":"American English","select":true},{"label":"British English"},{"label":"English"},{"label":"Scots English"}] 

请注意“美式英语”上的select属性。 这表示要自动完成我们要默认选择该项目。

然后,您将更新窗口小部件初始化代码以进入上述open事件。 这次虽然我们只是在搜索具有select属性的项目:

 $("input").autocomplete({ source: "autocomplete.php", open: function (event, ui) { var menu = $(this).data("uiAutocomplete").menu, i = 0, $items = $('li', menu.element), item, data; for (; i < $items.length && !item; i++) { data = $items.eq(i).data("ui-autocomplete-item"); if (data.select) { item = $items.eq(i); } } if (item) { menu.focus(null, item); } } }); 

示例: http //jsfiddle.net/J5rVP/42/

请注意,在上面的示例中,始终选择美式英语 。 由于自动完成function会在每次用户键入时发出新请求,因此您的服务器将使用不同的建议数据进行响应,从而响应不同的所选项目。

此外,我不知道PHP,所以我不能说你将如何实现将select属性添加到JSON。 看起来它会非常简单,甚至可能看起来像第一个使用正则表达式的示例中的JavaScript代码。

我建议您应该以不同方式查看映射数据,以便首先显示更高优先级的项目,例如以搜索词开头的单词。

然后,您可以按照自动完成/类别演示来分离结果。 这比尝试创建更改autoFocus代码要容易得多,你的排名更高,焦点会从那里开始

http://jqueryui.com/autocomplete/#categories

这是一个可以用来对结果进行排名的概念:

 function rankResult($str, $term){ /* 0 is first letters, 1 is in first word, 2 is starts another word, 3 is in word not first word*/ $words=explode(' ', $str); if(stripos($words[0],$term) !==false){ return stripos($words[0],$term)==0 ? 0 : 1; }else{ $rank=3; for( $i=1; $i< count( $words); $i++){ if(stripos($words[$i],$term)===0){ $rank=2; } } return $rank; } } $rank = rankResult('English', 'eng'); /*=> 0 */ 

循环:

  array('American English','British English','English','Scots English','HasEngInIt'); 

回:

 Array ( [0] => Array ( [label] => American English [rank] => 2 ) [1] => Array ( [label] => British English [rank] => 2 ) [2] => Array ( [label] => English [rank] => 0 ) [3] => Array ( [label] => Scots English [rank] => 2 ) [4] => Array ( [label] => HasEngInIt [rank] => 1 ) ) 

您必须进行一些排序,以便在发送到自动完成之前按等级对数据进行分组