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 的問題。

相關文章
相關標籤/搜索