以前使用過此 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 的問題。