[ASP.NET] jQuery UI MultiSelect Widget 下拉多選框

介紹使用 jQuery UI MultiSelect Widget 完成下拉多選框功能,並修改符合讓 Server 端存取。

前言


  最近碰到想使用 DropDownList 時,下拉的選項可以多選並取得其多選項目的需求,Google 了一下 jQuery 的 UI 發現了 jQuery UI MultiSelect Widget 這個 plugin ,看了之後覺得蠻符合需求的,順便在此紀錄一下。

 

基本使用方法


  首先到 jQuery UI MultiSelect Widget 下載相關 js 檔案,如下

  • jquery.multiselect.js
  • jquery.multiselect.css

 

  接著還需要具備 jQuery.js、jQuery UI.js、jQuery UI Theme,當以上檔案都有了之後就放入網站中,如下

 

  基本上如無須其他調整只需要在要使用的頁面上載入相關 js 檔案,並且配置相關 Script 與 HTML 內容,如下


<head runat="server">
    <title></title>
    <link href="css/ui-lightness/jquery-ui-1.9.2.custom.min.css" 
              rel="stylesheet" type="text/css" />
    <link href="css/jquery.multiselect.css" rel="stylesheet" type="text/css" />
    <script src="js/jquery-1.9.1.min.js" type="text/javascript"></script>
    <script src="js/jquery-ui-1.9.2.custom.js" type="text/javascript"></script>
    <script src="js/jquery.multiselect.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(function () {
            $("#<%= drpNames.ClientID %>").multiselect();
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:DropDownList ID="drpNames" runat="server">
            <asp:ListItem>Arvin</asp:ListItem>
            <asp:ListItem>Kevin</asp:ListItem>
            <asp:ListItem>Joyce</asp:ListItem>
            <asp:ListItem>Lisa</asp:ListItem>
        </asp:DropDownList>
    </div>
    </form>
</body>

 

  依照上方的代碼操作後將產生以下的結果。

 

讓 Server 端取得所選的項目


  基本使用方式瞭解後接下來就要讓 Server 端的程式碼能夠取得所選的下拉項目,首先增加一些 Tag 幫助顯示訊息與加入 ASP.NET Button 要用來取得值,在此可以透過 HiddenField 控制項來暫存所選取的項目,如下


<div>
    <div id="result"> </div>
    <div id="result2"> </div>
    <asp:DropDownList ID="drpNames" runat="server">
        <asp:ListItem>Arvin</asp:ListItem>
        <asp:ListItem>Kevin</asp:ListItem>
        <asp:ListItem>Joyce</asp:ListItem>
        <asp:ListItem>Lisa</asp:ListItem>
    </asp:DropDownList>
    <asp:Button ID="Button1" runat="server" Text="GetValues" 
        onclick="Button1_Click" />
    <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
    <asp:HiddenField ID="hfValues" runat="server" />
</div>

protected void Button1_Click(object sender, EventArgs e)
{
    Label1.Text = hfValues.Value;
}

 

  接著修改 plugin 的 Script ,加入對應的事件處理,關於事件處理可以參考該網站上的說明,另外說明一下在 SelectedText Event 中,可以取得所有選取的項目清單,所以要在 SelectedText Event 中加入將所選項目傳入之前所放置的 HiddenField  的 Value 中, 如下


$(function () {
    var $callback1 = $("#result");
    var $callback2 = $("#result2");
    var $callback3 = $("#<%= hfValues.ClientID %>");
    $("#<%= drpNames.ClientID %>").multiselect({
        click: function (event, ui) {
            $callback1.text(ui.value + ' ' + (ui.checked ? 'checked' : 'unchecked'));
        },
        uncheckAll: function () {
            $callback1.text("Uncheck all clicked!");
            $callback2.text('');
            $callback3.val('');
        },
        selectedText: function (numChecked, numTotal, checkedItems) {
            var values = $.map(checkedItems, function (checkbox) {
                return checkbox.value;
            }).join(", ");
            $callback2.text(values);
            $callback3.val(values);
            return numChecked + ' of ' + numTotal + ' checked';
        }
    });
});

 

  修改完成後就可能顯示所選取的項目,如下

 

  看上去很正常且已經可以取得所選的項目了,但是仔細再看一下會發現,在當所有選項都未選取時卻會殘留一個最後選取的項目不會清除,這樣就有可能造成當其實未選取任何項目時資料取得卻有還有一個項目的問題,所以針對這個問題我們需要修改此 plugin 的原始程式碼,開啟 jquery.multiselect.js 檔案找到 update: function () 此事件,如下


update: function () {
    var o = this.options,
	$inputs = this.inputs,
	$checked = $inputs.filter(':checked'),
	numChecked = $checked.length,
	value;

    if (numChecked === 0) {
        value = o.noneSelectedText;
    } else {
        if ($.isFunction(o.selectedText)) {
            value = o.selectedText.call(this, numChecked, $inputs.length, $checked.get());
        } else if (/\d/.test(o.selectedList) && o.selectedList > 0 && numChecked <= o.selectedList) {
            value = $checked.map(function () { return $(this).next().html(); }).get().join(', ');
        } else {
            value = o.selectedText.replace('#', numChecked).replace('#', $inputs.length);
        }
    }

    this.buttonlabel.html(value);
    return value;
},

 

  由以上代碼可以看到當 numChecked 為 0 時,並不會去呼叫 SelectedText Event ,所以在此需要多加入一段代碼讓當不選取任何項目時也要呼叫 SelectedText Event ,這樣我們才能在 SelectedText Event 中把 Value 清空,如下


if (numChecked === 0) {
    value = o.noneSelectedText;
    if ($.isFunction(o.selectedText)) {
        o.selectedText.call(this, numChecked, $inputs.length, $checked.get());
    }
} else {
    if ($.isFunction(o.selectedText)) {
        value = o.selectedText.call(this, numChecked, $inputs.length, $checked.get());
    } else if (/\d/.test(o.selectedList) && o.selectedList > 0 && numChecked <= o.selectedList) {
        value = $checked.map(function () { return $(this).next().html(); }).get().join(', ');
    } else {
        value = o.selectedText.replace('#', numChecked).replace('#', $inputs.length);
    }
}

 

  修改完成後再一次執行,結果如下

 

範例程式碼


TMultiselect.rar

 

參考資料


jQuery UI MultiSelect Widget

 

 


以上文章敘述如有錯誤及觀念不正確,請不吝嗇指教
如有侵權內容也請您與我反應~謝謝您 :)