我正在努力扩展jQuery自动完成功能,以便特定项目默认具有焦点。开箱即用的功能非常好用,但并不完美。使用autoFocus
选项,我可以自动关注第一项。
$( "#input" ).autocomplete({
source: "autocomplete.php",
minLength: 1,
autoFocus: true
});
但是,我希望能够更好地控制关注哪个项目。如果用户输入“eng”并且我的来源返回的相关项目是:
我希望第三项英语默认处于焦点(即实际以用户输入开头的项目,即使我想显示其他结果)。理想情况下,我的源代码 - autocomplete.php - 能够指出哪个项目是默认焦点。
有什么想法吗?我甚至不确定如何开始。
答案 0 :(得分:3)
利用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/(尝试搜索 E nglish或 S cots English)
代码使用本地数据源,但它应该与远程源一样好。
扩展上面的示例,您可以调整发送数据的方式,以便在每次搜索时,服务器端代码决定选择哪个项目。您只需在要选择的项目上指定其他属性即可。例如,您的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/
请注意,在上面的示例中,始终选择美式英语。由于自动填充每次用户输入时都会发出新请求,因此您的服务器会使用不同的建议数据进行响应,因此会选择不同的选定项目。
此外,我不知道PHP,所以我不能说你将如何实现将select
属性添加到JSON。看起来它会非常简单,甚至可能看起来像第一个使用正则表达式的示例中的JavaScript代码。
答案 1 :(得分:1)
我建议您应该以不同的方式查看映射数据,以便首先显示更高优先级的项目,例如以搜索词开头的单词。
然后,您可以按照自动完成/类别演示来分隔结果。这比尝试创建代码以更改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
)
)
您必须进行一些排序,以便在发送到自动填充之前按等级对数据进行分组