Quantcast
Channel: 黑暗執行緒
Viewing all articles
Browse latest Browse all 2311

Kendo UI AutoComplete一次搜尋多欄

$
0
0

專案用到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囉!

線上展示


Viewing all articles
Browse latest Browse all 2311

Trending Articles