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

NG筆記24-KendoAutoComplete花式應用

$
0
0

對於Kendo UI AutoComplete的Client端應用,過去的印象還停留在「提供字串陣列作為資料來源」、「指定contains、startswith、endswith進行比對」、「提示項目跟帶入欄位值都來自字串陣列」、「不能限定比對吻合項目上限」,感覺不如jQuery自動完成彈性。如以下範例:Live Demo

若要做到更特殊的比對邏輯或想限制提示筆數,倒是可用serverFiltering實現,將輸入關鍵字以AJAX方式交給伺服器端程式比對再傳回提示項目結果。但對SPA及打算包成App的情境,仰賴伺服器才能運作的自動完成有點掉漆。

最近為了專案的特殊需求,較深入了解KendoAutoComplete後,驚奇發現Kendo UI的架構比想像來得彈性,許多原以為辦不到的規格要求,並不難實現。

以下是KendoAutoComplete小露身手的花式操槍表演,展示重點包含:

  1. 股票資料以JavaScript陣列方式提供,完全在Client執行,不需伺服器端程式
    技巧:使用dataSource,可傳入物件陣列,不限定字串陣列,再以dataTextField指定取用屬性
  2. 提示區塊可指定不同寬度
    技巧:.data("kendoAutoComplete").list.width(…)可指定提示區寬度
  3. 關鍵字搜尋範圍涵蓋股票代號、中文名稱及英文名稱三個欄位
    技巧:dataSource.transport.read()可以自訂JavaScript函式進行比對,取代AJAX呼叫
  4. 提示項目呈現時,符合關鍵字的欄位(可能是代號、中文或英文三欄之一)靠左顯示,代號及中文名稱靠右顯示,關鍵字部分以紅字標示
    技巧:template參數可指定函式,接入資料物件,傳回動態組裝的HTML,完全掌控提示區顯示格式
  5. 選定提示項目時,只將股票代號填入欄位,中文名稱填入另外欄位,顯示於股票代號之後
    技巧:dataTextFiled參數指定要填入,在change事件可取得股票代號值變化,加入自訂邏輯連動其他欄位

程式碼如下:Live Demo


<!DOCTYPEhtml>
<htmlng-app="app">
<head>
<metacharset="utf-8">
<title>kendoAutoComplete範例:強化版</title>
<linkhref="//cdn.kendostatic.com/2014.2.716/styles/kendo.common.min.css"rel="stylesheet"/>
<linkhref="//cdn.kendostatic.com/2014.2.716/styles/kendo.default.min.css"rel="stylesheet"/>
<style>
        .hi {
            color: red;
        }
 
        .hint {
            clear: both;
        }
 
        .f-l {
            float: left;
        }
 
        .f-r {
            float: right;
        }
        .symbol {
            width: 100px;
        }
</style>
</head>
<bodyng-controller="ctrl as vm">
<div>
<inputclass="symbol"kendo-auto-complete="vm.KendoObject"
k-options="vm.Options"ng-model="vm.Symbol"/>
<spanng-bind="vm.Name"></span>
</div>
<scriptsrc="//code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script>
<script src="//cdn.kendostatic.com/2014.2.716/js/kendo.all.min.js"></script>
<script>
var rawData = [
    { s: '1435', c: '中福', e: 'C.F.C.Y.CORP.' },
    { s: '1437', c: '勤益', e: 'GTM' },
    { s: '1471', c: '首利', e: 'SL' },
//...省略...
    { s: '8078', c: '華寶', e: 'CCI' },
    { s: '8101', c: '華冠', e: 'Arima Comm.' },
    { s: '8105', c: '凌巨', e: 'GiantPlus' },
    { s: '8249', c: '菱光', e: 'CSI' },
    { s: '9912', c: '偉聯', e: 'AIC' }
        ];
var book = {};
        $.each(rawData, function(i, item) {
            book[item.s] = item;
        });
 
function myCtrl($scope) {
var self = this;
            self.Symbol = "";
            self.Name = "";
 
function hiliteKeywd(str, keywd) {
return str.replace(keywd, "<span class='hi'>" + keywd + "</span>")
            }
            self.Options = {
                dataTextField: 's',
                filter: "contains",
                template: function (item) {
return"<div class='hint'><span class='f-l'>" + item.match +
"</span><span class='f-r'>" + item.s + " " + item.c + 
"</span></div>";
                },
                open: function() {
//設定指示區寬度
                    self.KendoObject.list.width(250);
                },
                change: function() {
var symbol = this.value();
if (!symbol) 
                        self.Name = "";
else
//股票代號連動名稱
                        self.Name = book[symbol] ? book[symbol].c : "";
                },
                dataSource: {
                    serverFiltering: true,
                    transport: {
                        read: function (e) {
//密技:dataSource.transport可用JavaScript取代Server呼叫
var keywd = e.data.filter.filters[0].value;
//輸入數字時比對s、否則比對c或n
var isNum = !isNaN(keywd);
//設定比對筆數上限
var count = 0, maxCount = 10;
 
//共用比對函式
function check(item, prop) {
if (item[prop].indexOf(keywd) > -1) {
                                    count++;
                                    item.match = item[prop].replace(keywd,
"<span class='hi'>" + keywd + "</span>");
returntrue;
                                }
returnfalse;
                            }
 
var res = isNum ?
                              $.grep(rawData, function (item) {
if (count < maxCount && check(item, "s"))
returntrue;
else
returnfalse;
                              }) :
                              $.grep(rawData, function (item) {
if (count < maxCount && 
                                      check(item, "c") || check(item, "e"))
returntrue;
else
returnfalse;
                              });
//將比對結果傳回
                            e.success(res);
                        }
                    }
                }
            };
        }
        angular.module("app", ["kendo.directives"])
        .controller("ctrl", myCtrl);
</script>
</body>
</html>

補充:Kendo UI有兩個版本,Core版及Profession版。Core版免費並採Apache v2 Open Source授權;Profession版多了Grid、Charts、Editor、TreeView、Upload、Charts等元件,為付費商業元件。AutoComplete包含在Core版。

[NG系列]

http://www.darkthread.net/kolab/labs/default.aspx?m=post&t=angularjs

Viewing all articles
Browse latest Browse all 2311

Trending Articles