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