jQuery UI 自动完成:在模糊之后、ajax 请求完成之前完成我输入的内容?
假设我的 autocomplete 小部件有 2 个可能的选项:“JavaScript”和“jQuery”。如果我单击在输入中键入“j”,则会显示两个结果。现在假设我输入“q”,然后立即按 Tab 键。 “jq”只有一个可能的结果,那就是“jQuery”,但小部件无论如何都会选择“JavaScript”,因为 ajax 请求尚未返回,并且当我点击选项卡时“JavaScript”仍然突出显示。
有没有办法“解决”这个问题?即,我认为应该发生的是,我输入“jq”,点击选项卡,它在输入中留下“jq”,直到请求完成,然后当它完成时,选择第一个选项。
仍然无法使其发挥作用。我尝试在搜索时进行记录,并不允许像 Andrew 确实如此,但 loading
似乎从来都不是真的,所以我无法取消它......实际上,我认为这是因为 delay
尚未满足,下一个搜索甚至还没有开始......我必须将某些内容绑定到按键事件。
好的。我想我已经差不多明白了:
$('#myselector').autocomplete({
source: function(request, response) {
var data = {};
$(this.element).data('keyHandled', true).data('lastTerm', request.term);
// *snip*
$.ajax({
url: '/ajax/major_city',
dataType: 'json',
data: data,
success: function(data, textStatus, $xhr) {
response(data);
},
error: function($xhr, textStatus) {
response([]);
},
});
},
select: function(event, ui) {
if(!$(this).data('keyHandled')) {
// TODO perform another search for just one value and set the input immediately
return false;
}
this.value = ui.item.value;
$(this).trigger('change');
return false;
},
minLength: 0,
autoFocus: true,
delay: 250
})
.keydown(function(event) {
if($(this).val() !== $(this).data('lastTerm')) {
$(this).data('keyHandled', false);
}
});
如果用户在输入一堆内容后但在满足延迟/下一个搜索开始之前退出输入,这似乎可以正确地“取消”选择。现在我们可以执行另一个 ajax 调用,以根据输入中的内容获取单个“最佳匹配”值,然后进行设置。也无需再次弹出搜索窗口。
Let's say my autocomplete widget has 2 possible options: "JavaScript" and "jQuery". If I click type a "j" into the input, both results will appear. Now let's say I type "q" and then immediately hit tab. There is only one possible result for "jq" and that's "jQuery", but the widget selects "JavaScript" anyway because the ajax request hasn't come back yet and "JavaScript" was what was still highlighted when I hit tab.
Is there a way to "fix" this? i.e., I think what should happen is, I type "jq", hit tab, it leaves "jq" in the input until the request completes, and then when it does, picks the first option.
Still having trouble getting this to work. I tried recording when it was searching, and disallowing the select like Andrew does, but loading
never seems to be true, so I can't cancel it... actually, I think this is because the delay
hasn't been met and the next search hasn't even started... I'm going to have to bind something to the keypress event.
Okay. Think I've almost got it:
$('#myselector').autocomplete({
source: function(request, response) {
var data = {};
$(this.element).data('keyHandled', true).data('lastTerm', request.term);
// *snip*
$.ajax({
url: '/ajax/major_city',
dataType: 'json',
data: data,
success: function(data, textStatus, $xhr) {
response(data);
},
error: function($xhr, textStatus) {
response([]);
},
});
},
select: function(event, ui) {
if(!$(this).data('keyHandled')) {
// TODO perform another search for just one value and set the input immediately
return false;
}
this.value = ui.item.value;
$(this).trigger('change');
return false;
},
minLength: 0,
autoFocus: true,
delay: 250
})
.keydown(function(event) {
if($(this).val() !== $(this).data('lastTerm')) {
$(this).data('keyHandled', false);
}
});
This seems to properly "cancel" the select if the user tabbed out of the input after typing a bunch but before the delay was met/the next search started. Now we can perform another ajax call to grab a single "best match" value based on what's in the input and then set that. No need to pop open the search window again either.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我假设您的自动完成配置是将
autoFocus
选项设置为true
。考虑到这一点,您可以执行以下操作:跟踪 AJAX 调用是否正在进行。如果是这种情况,请不要允许用户从下拉列表中选择选项,直到该请求完成并且出现最新的匹配项。
您问题中唯一可能无法满足的部分是最后一部分(我可能误解了您在这里的要求):
这可能是可能的,但从可用性的角度来看,在最新鲜的项目出现之前禁止选择项目对我来说似乎更有意义。
毕竟,仅仅因为自动完成小部件有一个结果并不意味着用户在它最终出现时会想要选择它。
通过示例可能更容易理解:http://jsfiddle.net/RsSTa/。尝试输入“J”,然后输入“JQ”。您将无法继续使用过时的 AJAX 调用中的项目。
I'm assuming you're autocomplete is configured with the
autoFocus
option set totrue
. With that in mind, you could do something like this:Keep track of whether or not an AJAX call is in progress. If that's the case, don't allow the user to pick an option from the dropodown until that request has completed and the most recent matches come up.
The only part of your question that this may not satisfy is the last part (and I may be misunderstanding what you're asking for here):
This is probably possible, but from a usability standpoint it seems to make more sense to me to disallow selection of an item until the freshest items have appeared.
After all, just because one result is there for the autocomplete widget doesn't mean the user will want to select it when it finally does come up.
Probably easier to see with an example: http://jsfiddle.net/RsSTa/. Try typing "J" and then "JQ". You won't be allowed to continue with items from the stale AJAX call.
编辑4
使其成为一个函数。
使用情况:
现在效果很好。
Edit 4
Made it a function.
Usage:
Works pretty well now.