2012年12月20日 星期四

連動下拉選單 - 使用 jQuery EasyUI ComboBox

前一篇文章「jQuery 練習題:ASP.NET MVC 連動下拉選單與 jQuery UI Autocomplete ComboBox」是使用了 jQuery UI 的 Autocomplete ComboBox 來完成連動下拉選單的功能,其實想要在 ASP.NET MVC 網站裡做出 ComboBox 以及 Autocomplete 的功能也不是只能使用 jQuery UI,也可以使用其他的套件來完成,所以這一篇文章將會說明使用 jQuery EasyUI 的 ComboBox 來實作一個三層式的連動 ComboBox 選單功能。



jQuery EasyUI

http://www.jeasyui.com/

jQuery EasyUI 所強調的是讓我們可以用輕易的建立網站,集合了許多以 jQuery 為基礎所建立的 user-interface 套件,並且可以不必寫太多程式的情況下甚至透過設定在 HTML Tag 上的屬性就可以套用 jQuery EasyUI 的功能,另外就是它的 API 文件與線上範例還算相當清楚。

有玩過 Ext.JS 的朋友看到 jQuery EasyUI 一定會覺得相當眼熟,甚至會覺得這長得跟 Ext.JS 沒有什麼不同,我是不清處為何 jQuery EasyUI 的外觀有 Ext.JS 相同的外觀,但是一個是基於 jQuery 而另一個是有自己的 framework,如果專案並沒有考慮使用 Ext.JS 但又想要有類似的外觀與功能的話,是可以考慮使用 jQuery EasyUI。

image

 

jQuery EasyUI ComboBox

Demo
http://www.jeasyui.com/demo/main/index.php?plugin=ComboBox&theme=default&dir=ltr&pitem=

Documentation

http://www.jeasyui.com/documentation/combobox.php

image

jQuery EasyUI 官網上所提供的範例都是示範單一個 ComboBox 的應用,而我這邊是要把一個三層式連動下拉選單給改為三層式連動 ComboBox 選單,這裡是拿之前一篇文章的範例來做修改:「ASP.NET MVC 3 - 基本三層連動式下拉選單應用」,我稍微做了一點修改,程式的部份沒有變動,修改後的畫面如下,

image

最後我們使用 jQuery EasyUI ComboBox 修改為以下的樣貌,一樣保有在 ComboBox 輸入文字時的 Autocomplete 功能,

image

將原本的下拉選單給替換成 jQuery EasyUI ComboBox 並不需要修改 Controller 的程式,需要變動的是 View 的內容,
image

要把原本的 HTML Element 套用 jQuery EasyUI 的 Plugins 就是在 element 的 class attribute 加入相對應的 plugin 名稱就可以了,像上圖所框起來的地方,第一個使用 HtmlHelper 產生 DropDownList,也可以在 HtmlAttrubutes 裡加入 class,而一般的下拉選單直接加入 class attribute,另外就是 Orders 與 Products 下拉選單都是動態載入選項資料,而後端是以 JSON 來傳送資料,如下,

image

image

所以 Orders 與 Products 要轉換成 ComboBox 時,必須要在 data-options 內指定 valueField 與 textField,而這裡所指定的是接收 JSON 資料的欄位名稱,而第一個 Customers 下拉選單為何沒有指定 valueField 與 textField 呢?因為我在一開始的時候就有載入下拉選單的選項內容,而 jQuery EasyUI  ComboBox 除了可以套用在下拉選單上,也可以套用在 input 的 Html Element 上,套用在下拉選單上就會將下拉選單的選項分別指定 valueField 與 textField。

設定好 Html Element 的設定之後,接下來就是要進行 ComboBox 的事件處理,如下圖所示的內容,在 function CustomerEventHandler() 裡,依據 Documentation 的說明,分別在 filter 與 onSelect 做進一步的事件處理,

image

filter,當 ComboBox 有文字輸入時就會觸發這個事件,這裡就會對輸入文字來去比對 ComboBox 所載入的資料,預設 filter 是不必指定就會有預設的比對,但預設的比對是用完全比對的方式,所以當我們輸入英文字時是會區分大小寫的,為了要做不分大小寫的模糊比對就必須自己加入比對的程式,所以我這邊就在 filter 中加了不分大小寫的程式,傳回的值為 true 或 false,當傳回 true 時就會把有符合的項目給顯示在 ComboBox 選單中。

onSelect,當我們選定 ComboBox 的某個選項時要執行的內容。

Customers ComboBox 的選項內容是取用原本 Customers 下拉選單的內容,所以在 onSelect 的事件中要取得選定的選項值是取用 item.value,但到了 Orders ComboBox 的 onSelect 這裡卻不是,而是取用 valueField 所指定的 JSON 資料欄位名稱,如下圖所示,

image

假如我們把 Orders ComboBox 所接收到的 JSON 資料欄位名稱都改為其他名稱(當然在 Controller Action 的程式也做了修改),如下:

image

那麼 Orders ComboBox 的 onSelect 就要做變動,

image

在第一個 Customers ComboBox 的 onSelect 中讓第二個 Orders ComboBox 動態載入選項資料,然後在第二個 Orders ComboBox 的 onSelect 裡讓第三個 Products ComboBox 動態載入資料,如此一來做到了連動的功能。

最後就是 Products ComboBox 選定某一個項目後要取得選到的選項值,這個在 jQuery EasyUI 的 Documentation 中卻找不到,不過倒是在範例裡卻有正確的方法,所以取得選取選項的值使用 getValue 就可以了,如下圖,

image

 

以上就是幾個比較重點的地方,下面就提供前端的程式內容,

View

<h2>@ViewBag.Message</h2>
<div>
    <span>
        Customers:
        @Html.DropDownList(
            "Customers", 
            (SelectList)ViewBag.CustomerList, 
            "", 
            new { id = "Customers", @class="easyui-combobox", style="width: 150px;" })
    </span>
    <span>
        Orders:
        <select id="Orders" name="Orders" style="width: 150px;" 
            class="easyui-combobox" 
            data-options="valueField:'Key',textField:'Value'">
            <option></option>
        </select>
    </span>
    <span>
        Products:
        <select id="Products" name="Products" style="width: 200px;" 
            class="easyui-combobox" 
            data-options="valueField:'Key',textField:'Value'">
            <option></option>
        </select>
    </span>
    <p>
        <input type="button" id="ButtonReset" value="清除" />
        <input type="button" id="ButtonSubmit" value="顯示產品資訊" />
    </p>
    <hr />
    <div id="ProductInfo"></div>
</div>

Javascript

<script type="text/javascript">
    $(document).ready(function () {
        CustomerEventHandler();
 
        $('#ButtonSubmit').hide().click(function () { DisplayProductInfo(); });
        $('#ButtonReset').click(function () { ResetContent(); });
    });
 
    function CustomerEventHandler() {
        $('#Customers').combobox({
            filter: function (q, row) {
                return (row.text.toLowerCase().indexOf(q) >= 0 || row.text.toUpperCase().indexOf(q) >= 0);
            },
            onSelect: function (customerItem) {
                ChangeCustomerList($.trim(customerItem.value));
            }
        });
    }
 
    function ChangeCustomerList(customerID) {
        if (customerID.length > 0) {
            $('#Orders').combobox({
                url: '/Home/Orders?customerID=' + customerID,
                filter: function (q, row) {
                    return (row.Value.toLowerCase().indexOf(q) >= 0 || row.Value.toUpperCase().indexOf(q) >= 0);
                },
                onSelect: function (orderItem) {
                    ChangeOrderList($.trim(orderItem.Key));
                }
            });
        }
    }
 
    function ChangeOrderList(orderID) {
        if (orderID.length > 0) {
            $('#Products').combobox({
                url: '/Home/Products?orderID=' + orderID,
                filter: function (q, row) {
                    return (row.Value.toLowerCase().indexOf(q) >= 0 || row.Value.toUpperCase().indexOf(q) >= 0);
                },
                onSelect: function (productItem) {
                    var productID = $.trim(productItem.Key);
                    if (productID.length > 0) {
                        $('#ButtonSubmit').show();
                    }
                    else {
                        $('#ButtonSubmit').hide();
                        $('#ProductInfo').empty();
                    }
                }
            });
        }
    }
 
    function DisplayProductInfo() {
        var selectedValue = $('#Products').combobox('getValue');
        if ($.trim(selectedValue).length > 0) {
            $.ajax({
                url: '@Url.Action("ProductInfo", "Home")',
                data: { productID: selectedValue },
                type: 'post',
                cache: false,
                async: false,
                dataType: 'html',
                success: function (data) {
                    if (data.length > 0) {
                        $('#ProductInfo').empty();
                        $('#ProductInfo').html(data);
                    }
                }
            });
        }
    }
 
    function ResetContent() {
        $('#Customers').combobox('clear');
        $('#Orders').combobox('clear');
        $('#Products').combobox('clear');
        $('#ProductInfo').empty();
        CustomerEventHandler();
    }
</script>

 

ComboBox 中輸入文字,ComboBox 自動帶出還有輸入文字的項目,

image

第一個 ComboBox 選定項目後就讓第二個 ComboBox 載入選定 Customer 的 Order 資料內容,

image

選擇好 Orders 的選項後載入 Products ComboBox 的項目資料,

image

第三個 Products ComboBox 選定項目後就會顯示「顯示產品資訊」按鍵,

image

顯示產品資訊

image

 

如果對於英文的 Documentation 閱讀覺得不習慣的話,可以看看對岸有人整理的「jQuery EasyUI 中文幫助手冊」,不過版本與 jQuery EasyUI 官網的 Documentation 不同,所以有些內容在中文幫助手冊上面是沒有的,不過也是具有參考價值的。

jQuery EasyUI 中文幫助手冊http://www.phptogether.com/juidoc/

 

以上

沒有留言:

張貼留言

提醒

千萬不要使用 Google Talk (Hangouts) 或 Facebook 及時通訊與我聯繫、提問,因為會掉訊息甚至我是過了好幾天之後才發現到你曾經傳給我訊息過,請多多使用「詢問與建議」(在左邊,就在左邊),另外比較深入的問題討論,或是有牽涉到你實作程式碼的內容,不適合在留言板裡留言討論,請務必使用「詢問與建議」功能(可以夾帶檔案),謝謝。