专注于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 ) )
您必须进行一些排序,以便在发送到自动完成之前按等级对数据进行分组