Kendo UI AutoComplete一次搜尋多欄

專案用到Kendo UI的自動完成,提示資料的物件陣列存在Client端,資料有多個欄位,希望做到任一個欄位包含關鍵字就顯示,AutoComplete有個filter參數,設定為"contains"就可以做到"包含"就算數,但搜尋對象參數dataTextField卻只能指定單一欄位,無法一次查詢多欄。

有個解決辦法是自行在物件上將多個欄位另外併成一欄,例如以下的codePage物件,textForSearch屬性等於代碼加空白加名稱:

      var $code = $("#code");
      function codePage(code, name) {
        this.codePage= code;
        this.name = name;
        this.textForSearch = code + " " + name;
      }
      var data = [
        new codePage("869", "Greek"),
        new codePage("932", "Japanese"),
        new codePage("936", "Simplified Chinese"),
        new codePage("949", "Korea"),
        new codePage("950", "Traditional Chinese")
      ];
      $code.kendoAutoComplete({
        dataTextField: "textForSearch",
        dataValueField: "codePage", 
        dataSource: data,
        filter: "contains",
        select: function (e) {
            //get index of <LI>
            var idx = $.inArray(e.item[0], e.sender.items());
            var data = e.sender.dataItem(idx);
            //set name
            $("#name").text(data.name);
        }
      });

如此,將dataTextField設為textForSearch就能同時搜尋CodePage代碼及名稱:

但有個問題,雖然欄位輸入CodePage代碼或名稱都能搜尋,但我們希望自動完成欄位固定只輸入代碼,名稱則由另一個<SPAN>顯示。當AutoComplete的dataTextField設為textForSearch,點選提示項目後欄位填入的也會是textForSearch的值,會同時有代碼及名稱,與期望不符。

要解決這個問題,有個不錯的方法是透過dataValueField參數指定要填入<INPUT>的屬性名稱。要增加dataValueField功能得修改Kendo UI原始碼,不過修改3rd Party程式庫會增加版控複雜性,追完原始碼,我找到事後置換kendoAutoComplete物件的_select函式的玩法,可不修改原始碼JS就加入新功能,於是用以下的"Patch"函式,傳入data("kendoAutoComplete")取得的物件,將.select換成修改版(其實只改了一行),完成Hacking:

    var SELECTED = "k-state-selected", List = kendo.ui.List;
    function patchKendoAutoComp(autoCompObject) {
        //add optionValueField support to 2013.2.716 version 
        autoCompObject._select = function (li) {
            var that = this,
                separator = that.options.separator,
                data = that._data(),
                text,
                idx;
 
            li = $(li);
 
            if (li[0] && !li.hasClass(SELECTED)) {
            
                idx = List.inArray(li[0], that.ul[0]);
 
                if (idx > -1) {
                    data = data[idx];
                    //if dataValueField provided, use _value
                    text = that.options.dataValueField ? that._value(data) : 
                           that._text(data);
 
                    if (separator) {
                        text = replaceWordAtCaret(caretPosition(that.element[0]), that._accessor(), text, separator);
                    }
 
                    that._accessor(text);
                    that.current(li.addClass(SELECTED));
                }
            }
        }
    }

為AutoComplete增加dataValueField參數有助提高應用彈性,在官方討論區PO了提議,希望未來有機會加入規格,就不需要這個額外Hacking囉!

線上展示

歡迎推文分享:
Published 08 August 2013 10:36 PM 由 Jeffrey
Filed under:
Views: 8,720



意見

# 吳宇 said on 08 August, 2013 12:03 PM

請問黑大,

試用了Kendo UI 一陣子,有個問題想請教,UI總是透過美工設計,但是 Kendo UI 似乎包好好,要調到與美工設計的很接近,都需要花很多時間,不知黑大用在專案中是否有類似的情形?

# Jeffrey said on 08 August, 2013 08:22 PM

to 吳宇, 同意,Kendo UI預設的視覺風格,的確與中文網頁一般慣用的樣式有些差異(中文網頁多半字體較小,排列較緊密),要貼近自家美工設計需要耗費一番工夫是事實。依我自己的經驗,Kendo UI採用的CSS套用規則還算模組化,配合IE Dev Tools直接由看到的網頁元素去反推CSS來源,修改後重整就可看結果,調整過程還算直覺流暢,個人覺得痛苦指數在可承受範圍內。

調整樣式是不管用哪一家的UI套件都會面臨的問題,故可把它視為專案中無法逃避的客製工程排入時程。等處理CSS的經驗多了加上熟能生巧,這就不太會是問題了。

# 吳宇 said on 08 August, 2013 09:06 PM

謝謝黑大

# benson said on 28 November, 2014 04:22 AM

AutoComplete确实不会搜多列,所以我做了个dropSearch,可以指定单列或多列搜,像智能手机查联系人时,输数字,按电话号码查,输中文,按联系人姓名或地址等搜查,演示地址:

jsfiddle.net/.../1y1zgaku

# Jeffrey said on 01 December, 2014 04:15 AM

to benson, 感謝分享!

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 
(提醒: 因快取機制,您的留言幾分鐘後才會顯示在網站,請耐心稍候)

5 + 3 =

搜尋

Go

<August 2013>
SunMonTueWedThuFriSat
28293031123
45678910
11121314151617
18192021222324
25262728293031
1234567
 
RSS
創用 CC 授權條款
【廣告】
twMVC
最新回應

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


Syndication