jQuery大神幫你做後台–Select篇

jQuery大神幫你做後台–Select篇

記得一開始寫ASP.NET的時候

免不了會有一些很常出現的DropDownList選單

 

例如說鄉鎮選單、產品類別選單之類的

那些資料都是從資料庫去維護的

 

==============================================================

為了不重複在每個會用到那個DropDownList的頁面重複寫一樣的程式碼

 

會習慣把那個下拉選單做成一個UserControl

 

在裡面把撈資料的邏輯寫好

 

 

之後拉到不同的頁面就好

 

==============================================================

而在撈資料的時候


	Photo[] items = new PhotoBaseDb().GetAll();
        DropDownList1.DataSource = items;
        DropDownList1.DataTextField = "TextColumn";
        DropDownList1.DataValueField = "ValueColumn";
        DropDownList1.DataBind();

我們可以用很簡單的方法取出物件

並且把屬性名稱指定給DropDownList

 

接著呼叫DataBind()

就可以藉由ASP.NET提供的機制  做出一個下拉選單

 

 

==============================================================

那假如我們想用jQuery辦到這兩件事

 

1. 跨頁面重複使用同樣的select,  不要重複寫

2. 用簡單的方法指定資料來源後, 將資料自動榜上select, 而不用自己寫一堆程式

 

 

一定也是有方法的,  下面就分享我個人一點淺薄的做法,  就當成做筆記

首先還是老調重彈

 

我們程式一樣從Client端出發, 跟Server端要資料

那就是要選擇PageMethod, 還是泛型處理常式ashx的問題了

 

在這邊我選擇ashx,  因為這隻程式希望能在每一頁都能夠呼叫

所以我選擇了單獨放在 {專案WebSite} \ Services \ SelectHandler.ashx 這隻程式做編寫

 

從資料夾的命名可以看得出來,  Services裡面我放了很多支的ashx,  可以讓不同頁面重複呼叫

要維護也比較直覺

 

而程式就簡單的舉例如下


	using System;
using System.Web;
using System.Web.Script.Serialization;

public class SelectHandler : IHttpHandler {
    
    public void ProcessRequest (HttpContext context) {
        Student[] students = Student.GetAll();

        context.Response.ContentType = "application/json";
        context.Response.Charset = "utf-8";
        context.Response.Write(new JavaScriptSerializer().Serialize(students));
    }
 
    public bool IsReusable {
        get {
            return false;
        }
    }

    public class Student
    {
        public static Student[] GetAll()
        {
            //到資料庫撈資料出來, 物件化成Student Array的程式 
            //依照各專案不同的商業邏輯而定
            return new Student[0];
        }
        public int StudentId { set; get; }
        public string Name { set; get; }
        public int Age { set; get; }
    }
}

 

可以看到規畫了一個很簡單的Student Class,

以及取得全部資料, 並且序列化成JSON之後輸出的ashx

 

 

於是對我們的jQuery而言,  我們有了一個source, 可以提供給他現在有哪些學生的資訊

 

而可以再寫一段dataBind的程式如下


	$.fn.dataBind = function (options) { //把傳入的物件Bind進Select
            var p = options || {}; //如果option不存在, 則指定一個空物件過去, 方便之後判斷

            if (p.defaultItem) { //如果有預設item
                if (p.defaultItem == true) p.defaultItem = {};//假如只有給true, 則先宣告為物件, 後方會有程式指定預設值給他
                if (typeof p.defaultItem == 'string') p.defaultItem = { text: p.defaultItem }; //假如只有給文字, 則轉成我們預設的物件格式
                if (typeof p.defaultItem == 'number') p.defaultItem = { value: p.defaultItem };   //假如只有數值, 則轉成我們預設的物件格式
                if (typeof p.defaultItem == 'object') {
                    if (!p.defaultItem.text) p.defaultItem.text = 'select'; //假如名稱不存在, 則指定他為select
                    if (!p.defaultItem.value) p.defaultItem.value = -999; //假如數值不存在, 則指定為-999
                }
                else
                    p.defaultItem = undefined;
            }

            var textField = p.textField || 'text';
            var valueField = p.valueField || 'value'; //要對應到傳回來物件的哪個屬性

            var data;

            if (p.url) {
                $.ajax({
                    url: p.url, type: p.type || 'GET', data: p.data || {}, //使用AJAX取得資料
                    async: false, //為了便於閱讀所以設為false, 但這是很不好的做好, 實際上可以用其他回乎函數作放資料的動作來取代
                    success: function (obj) { data = obj; }
                });
            }

            return this.each(function () {
                if (!data) return;
                var $select = $(this);
                $select.empty();

                if (p.defaultItem) //假如有預設值, 則加進select中
                    $select.append('<option value = "' + p.defaultItem.value + '">' + p.defaultItem.text + '</option>');

                $.each(data, function () {
                    var text = this[textField] || '';
                    var value = this[valueField] || '-999';

                    $select.append('<option value = "' + value + '">' + text + '</option>')
                });
            });
        };

 

簡單說明如下,

幫jQuery擴充了一個fn : dataBind,

 

用處是指定取得物件的位置,  text要對應到哪個屬性,  value要對應到哪個屬性

之後把物件娶回來並且轉成option放進select的動作

 

可以看到4~14行花了10寫一堆落落長的東西,  就只是為了宣告一個預設的選項 <option value='-999'>select</option>

會寫這麼多行完全是因為懶人作法

 

因為這個UI程式寫出來後,  希望可以在不同地方都套用這支程式做dataBind進Select的動作

所以希望程式能活一點

 

因此預設了各種情況,  假如defaultItem是true, 是string, 是value,  都有辦法轉成最後我要的格式

這樣我之後在使用的時候就可以視情況傳我要的參數進來

 

 

而最後,  所謂的dataBind動作,  充其量也不過是把傳回來的物件跑個迴圈,  使用指定的textField跟valueField把對應的值取出來組成option的動作而已

 

=======================================================================================

而寫好這支程式後,

 

之後在其他頁面假如希望能有一個學生選單,  我只需要用這行


	<select id='ddlStudent'></select>
    <script type="text/javascript" language='javascript'>
        $('#ddlStudent').dataBind({ url: 'SelectHandler.ashx', valueField: 'PhotoId', textField: 'FileName', defaultItem: true });
    </script>

 

很簡單吧,

而且其實可以透過option的預設值動作,  讓程式碼變得更乾淨

 

假如試成功這樣的寫法後

 

也可以舉一反三自己寫出作radioButton或是checkBox的dataBind了

 

 

 

而這篇有稍微用到一點$.fn 這種擴充的寫法

 

這已經算是寫jQuery UI的入門

 

下一篇預計分享寫jQuery的小心得  就希望大家不吝指教了

 

--

本文可能有理解錯誤  或不盡不實的地方

請路過的前輩不要客氣  用力打醒

這會是我們成長的主要養分