仅在输入光标时如何显示easyautocomplete对话框 [英] How show easyautocomplete dialog only if cursor is in input
问题描述
我正在尝试在输入中设置easyautocomplete.我从ajax json获取数据集,并且有一些延迟.如果用户太快并且写例如"Adam"并按Tab,光标将跳至下一个输入,但是在easyautocomplete之后,上一个输入将显示对话框,并且不会隐藏它.只有当我有光标输入时,有什么方法可以显示easyautocomplete对话框吗?
I'm trying set easyautocomplete on my input. Dataset i am geting from ajax json and there is some delay. If user is too fast and writes for example "Adam" and pushes tab, cursor skips to next input, but after easyautocomplete shows dialog on previous input and doesn´t hide it. Is there any way how to show easyautocomplete dialog only when i have cursor in input?
var options = {
minCharNumber: 3,
url: function(phrase) {
return "data?q=" + phrase;
},
getValue: function(element) {
return element.surname + " " + element.name;
},
template: {
type: "description",
fields: {
description: "phone"
}
},
ajaxSettings: {
dataType: "json",
method: "POST",
data: {
dataType: "json"
}
},
list: {
onClickEvent: function() {
/*Some action*/
},
hideAnimation: {
type: "slide", //normal|slide|fade
time: 400,
callback: function() {}
}
},
requestDelay: 400
};
$(".autoComplete").easyAutocomplete(options);
推荐答案
最小,完整,可验证的示例
为了轻松查看此结果,您必须打开开发工具并限制网络流量,以便ajax连接花费一些时间
Minimum, Complete, Verifiable, Example
In order to easily see this result, you'll have to open up your dev tools and throttle your network traffic so the ajax connection takes a little while
我最初的想法是,您可以在某些 EAC生命周期事件中处理此问题.触发的内容,例如onLoadEvent
或onShowListEvent
:
My initial thought was you could handle this during some of the EAC lifecycle events that fired, like the onLoadEvent
or onShowListEvent
:
var options = {
url: "https://raw.githubusercontent.com/KyleMit/libraries/gh-pages/libraries/people.json",
getValue: "name",
list: {
match: {
enabled: true
},
onLoadEvent: function() {
console.log('LoadEvent', this)
},
onShowListEvent: function() {
console.log('ShowListEvent', this)
}
},
};
但是,这些方法似乎没有提供改变控制流并防止将来发生事件的选项
However, these methods don't seem to provide an option to alter the control flow and prevent future events
Easy AutoComplete观察库的源代码,执行以下操作...
Peeking into the library's source code, Easy AutoComplete does the following ...
然后调用 loadData
哪个会触发带有提供的URL的AJAX请求
取决于网络和服务器的速度,在步骤4之前可以经过任何时间,并且输入内容可能会失去焦点
一旦返回了ajax许诺,将调用 showContainer()
Once the ajax promise is returned, will call showContainer()
在第6步中,我们可以添加最后一个检查以确认所选输入在实际打开之前仍具有焦点,如下所示:
During step 6, we could add one last check to confirm the selected input still has focus before actually opening, which would look like this:
$elements_container.on("show.eac", function() {
// if input has lost focus, don't show container
if (!$field.is(":focus")) {return}
// ... rest of method ...
> 这是在Plunker中运行的演示 库文件的新文件中的源代码
Here's a working demo in Plunker which modifies the library's source code in a new file
不幸的是,这不是一个好习惯,因为它使您对将来的更改很脆弱,并且将lib维护的所有权转移到您的代码库中.但这确实有效.
Unfortunately, that's not a great practice as it leaves you fragile to future changes and transfers ownership of the lib maintenance to your codebase. But it does work.
我使用建议的更改创建了请求#388 库本身内的术语修复将在将来的某个时候提供.
I created Pull Request #388 with the proposed changes, so hopefully a long term fix within the library itself will be available at some point in the future.
如果您不希望使用第三方代码,则有一些怪异的解决方法会干扰内部执行.我们无法修改showContainer
方法,因为它位于闭包内部.
If you don't want to muck with third party code, there are some weird workarounds to mess with the internal execution. We can't modify the showContainer
method since it's inside a closure.
我们可以在show.eac
事件上添加另一个侦听器,因此我们可以成为事件管道的一部分,但是这里也存在一些挑战.理想情况下,我们希望在执行库处理程序并有条件地停止传播之前触发.但是,初始化EAC会:a)创建我们必须监听的容器,并且b)附加一个事件监听器.
We can add another listener on the show.eac
event so we can be a part of the event pipeline, however there are some challenges here too. Ideally, we'd like to fire before the library handler is executed and conditionally stop propagation. However, initializing EAC will both a) create the container we have to listen to and also b) attach an event listener.
注意: jQuery中的事件处理程序将按其附加顺序触发!
因此,我们必须等到lib加载后才能附加我们的处理程序,但这意味着我们只会在列表显示后才触发.
So, we have to wait until after the lib loads to attach our handler, but that means we'll only fire after the list is already displayed.
从问题如何订购与jQuery绑定的事件,我们可以进入jQuery内部并重新排序事件,因此我们可以在调用库的处理程序之前触发处理程序.看起来像这样:
From the question How to order events bound with jQuery, we can poke into the jQuery internals and re-order attached events so we can fire our handler before the library's handler is called. That'll look like this:
$._data(element, 'events')["show"].reverse()
注意:
e.stopPropagation()
和e.preventDefault()
都不起作用,因为它们阻止了将来的事件;相反,我们需要对e.stopImmediatePropagation()
Note: Both
e.stopPropagation()
ande.preventDefault()
won't work since they prevent future events; instead we need to take more immediate action withe.stopImmediatePropagation()
因此包装器将如下所示:
So the wrapper would look like this:
$("#countries").easyAutocomplete(options);
$(".easy-autocomplete-container").on("show.eac", function(e) {
var inputId = this.id.replace('eac-container-','')
var isFocused = $("#"+inputId).is(":focus")
if (!isFocused ) {
e.stopImmediatePropagation()
}
});
$(".easy-autocomplete-container").each(function() {
$._data(this, 'events')["show"].reverse()
})
这篇关于仅在输入光标时如何显示easyautocomplete对话框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!