仅在输入光标时如何显示easyautocomplete对话框 [英] How show easyautocomplete dialog only if cursor is in input

查看:87
本文介绍了仅在输入光标时如何显示easyautocomplete对话框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在输入中设置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

这是jsFiddle中该问题的演示

我最初的想法是,您可以在某些 EAC生命周期事件中处理此问题.触发的内容,例如onLoadEventonShowListEvent:

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 ...

  1. 处理键盘锁事件

然后调用 loadData

哪个会触发带有提供的URL的AJAX请求

取决于网络和服务器的速度,在步骤4之前可以经过任何时间,并且输入内容可能会失去焦点

一旦返回了ajax许诺,将调用 showContainer()

Once the ajax promise is returned, will call showContainer()

触发容器上的"show.eac"事件

然后用选定的动画打开列表

在第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() and e.preventDefault() won't work since they prevent future events; instead we need to take more immediate action with e.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()
})

> 这是CodePen中的有效演示

这篇关于仅在输入光标时如何显示easyautocomplete对话框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆