zoukankan      html  css  js  c++  java
  • jQuery Autocomplete 备忘录

    之前使用过此 widget,如今再次需要,发现很多东西已经记不起来了,当然之前用的版本也不一样。

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

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

    先看使用代码:

    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();
                    }
                }
            });
    }
    

      

    问题一:

    有一个初始值,当页面加载后,赋值文本框,自动执行搜索,然后选取记录(single item 只有一条结果记录)。为什么这样做,是因为需要触发 select 事件。

    该怎么办呢?

    解决方案:

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

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

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

    2、开始以为,只要 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 的问题。

  • 相关阅读:
    zookeeper端口号冲突:8080冲突
    Linux 开机报 or type Control-D to continue
    linux分区和系统文件和挂载
    linux添加JAVA环境变量
    root用户安装的软件在普通用户不生效
    微信小程序:text元素中加入空格
    Java Swing:JPanel添加边框
    Java Swing:JPanel中添加JPanel
    Spring Boot:项目打包成war并发布到Tomcat上运行
    IDEA将MAVEN项目打包成war包
  • 原文地址:https://www.cnblogs.com/ranmofang/p/6035794.html
Copyright © 2011-2022 走看看