jQuery Autocomplete 备忘录

以前使用过此 widget,现在再次须要,发现不少东西已经记不起来了,固然以前用的版本也不同。javascript

使用以前固然是先认真阅读官方的说明文档和示例,这点很重要,而不是东一块西一点的去网上瞎找资料。Options,Methods,Events 区分的很详细,参考 jQuery Autocomplete Widget API DOC 。html

我须要的场景是,一个文本框,根据动态输入,ajax get data source,select 结果后作些 dom 操做。这是一个简单场景,固然我须要的其实很复杂,后面讲。先说我遇到的问题。java

先看使用代码:jquery

function registerAuto() {
    var autoId = "cust-code";
    $("#" + autoId)
        .autocomplete({
            source: function(request, response) {
                var term = $.trim(request.term);
                //term.replace("$", "") only replace the first match one
                if (term.length === 0 || $.trim(term.split("$").join("")).length === 0) {
                    return;
                }
                $.ajax({
                    url: "/order/aeo/customer",
                    method: "post",
                    dataType: "json",
                    data: { keywords: term },
                    success: function(data) {
                        response(data);
                    }
                });
            },
            delay: 800,
            autoFocus: true,
            minLength: 2,
            position: { my: "left bottom", at: "left top" },
            select: function(event, ui) {
                //console.log(ui);
                showCustomer(ui.item.value);
            },
            change: function(event, ui) {
                //console.log(ui);
                if (!ui.item) {
                    $("#" + autoId).val("");
                    hideCustomer();
                }
            }
        });
}

  

问题一:ajax

有一个初始值,当页面加载后,赋值文本框,自动执行搜索,而后选取记录(single item 只有一条结果记录)。为何这样作,是由于须要触发 select 事件。json

该怎么办呢?api

解决方案:app

一、最简单的办法就是:赋值文本框,而后手动调用 select 里面须要执行的方法,不须要执行 autocomplete。dom

 $(function() {
     registerAuto();
     $("#cust-code").val("@Model.CustomerCode");
     showCustomer("@Model.CustomerCode");
 });

如上代码就好了,可是本人很倔,就是要 autocomplete 方式,手动的去调用它的方法去触发事件。ide

 

二、开始觉得,只要 focus 文本框,而后赋值文本就会触发自动搜索事件,结果是根本不行的。

辛苦搜索了不少资料,以 jquery autocomplete manually search 关键信息才找到解决方法。

 $(function() {
     registerAuto();
     $("#cust-code").val("@Model.CustomerCode");
     $("#cust-code").autocomplete("search");
 });

代码触发 search 事件,但问题又来,怎么实现自动 select 结果呢?使用的是投机的方式,根据生成的 items ui 去 click 标签。

 $(function() {
     registerAuto();
     $("#cust-code").val("@Model.CustomerCode");
     $("#cust-code").autocomplete("search");
     setTimeout(function() {
         $(".ui-menu-item").click();
      }, 100);
  });

其中的 setTimeout,是为了有足够的时间等待 ajax 返回结果。

好了上面问题是解决了,但一个终极问题,应该也是不少人遇到的问题,却须要亟待解决。

 

问题二:

ajax 返回结果太多,如何动态分页的去获取结果,而不是一次性加载呢?

解决思路:

本身想到了一个方案:搜索结果有滚动条,当滚动条到底部时,自动加载下一页结果,直到所有加载完。其实,用户可能只加载几页,找不到结果就换关键词从新搜索了。

但遇到的难题是:怎么把动态加载的结果,append 到 autocomplete 的 data source 里面,由于其余事件(如 select )须要。

又想到的解决是:修改 autocomplete 源码,增长扩展方法;或者绑定事件到 items ui 上,如 scroll bar 加载方法,click select 方法等。

解决方案:

总之目前没有实现,不知道诸君有何建议?

 

 

2016-11-25

最近的使用,又有一些新的需求,而后又找到了一些解决方案,总之是越用越顺手了。

问题三:

autocomplete 默认接受的对象是这样的 { label : "label", value : "value" } ,但使用时须要显示更多的 label 数据,以及须要获取除 value 以外的其余数据,怎么办呢?

简单的解决办法:

lablel 拼接数据显示,但不能用 html 作丰富显示,由于都看成字符串。

value 也以必定规则拼接,可是最后 value 要展现在 input 中,看起来很不友好。

终极解决方案:

使用 _renderItem 扩展解决 label 问题,自定义显示内容;

因为 autocomplete 是将 source 保存起来的,所以 response(data) 的时候去了 label 和 value 外,能够自定义其余属性,或者 label 使用一个对象。

 $(".auto-stock")
        .autocomplete({
            source: function(request, response) {
                var term = $.trim(request.term);
                if (term.length === 0) {
                    return;
                }
                $.getJSON("/api/query",
                    { keyword: term },
                    function(data) {
                        //data 类型假设是 { id, code, name, type }
                        response($.map(data,
                            function() {
                                return { label: data, value: data.name };
                                //或者 
                                //return { label: name, value: data.name, code : data.code, id : data.id };
                            }));
                    });
            },
            delay: 100,
            autoFocus: true,
            minLength: 2,
            position: { my: "left top", at: "left buttom" },
            select: function(event, ui) {
                //console.log(ui.item);
                //这里能够得到自定义 label 对象,或者其余属性
                setQuery(ui.item.label);
            },
            change: function(event, ui) {
                //console.log(ui);
                if (!ui.item) {
                    $(this).val("");
                }
            }
        })
        .data("ui-autocomplete")
        ._renderItem = function(ul, item) {
            return $("<li>")
                .attr("data-value", item.value)
                //自定义显示 ui
                .append("<div><dd>" + item.label.code + "</dd><dd>" + item.label.name + "</dd><dd>" + item.label.type + "</dd></div>")
                .appendTo(ul);
        }

对 autocomplete 的使用又多了一些心得,其余下次有须要时,解决掉 pagination 的问题。

相关文章
相关标签/搜索