用jQuery做連動式下拉選單(3/30日更新)

用jQuery做連動式下拉選單

最近在學jQuery,剛好看到demo大的一篇文章ASP.NET MVC 連動式下拉式選單

想說這個以後一定用的到,就實際的動手做做看。

首先先建了一個Table來放台灣各縣市的縣市名跟郵遞區號

b598ebf83ce042e8b439c25d190536a9

然後再將資料Insert進去

6dea5da9801c491c89f79ca298a6b43f

之後就再MVC專案中拉近一個Linq to SQL 準備等下來撈資料庫裡的資料。

直接擴充兩個Helper

分別是縣市的下拉選單,跟地區+郵遞區號的下拉選單


    {
        //地區的下拉選單
         public static string Region(this HtmlHelper helper, string id, string name)
        {
            MyDataContext db = new MyDataContext();

            //建立一個TagBuilder
            TagBuilder tag = new TagBuilder("select");
            
             //將傳入的id跟name分別設到id屬性跟name屬性
             tag.GenerateId(id);
            tag.MergeAttribute("name", name);
            var data=from n in db.Regions select n.Region_縣市;
            tag.InnerHtml = "<option value='0'>請選擇縣市</option>";
             //從資料庫撈地區資料,然後加到option
            foreach (var m in data.Distinct())
            {
                tag.InnerHtml += "<option class='sub_" + m + "' value='" + m + "'>" + m + "</option>";
            }
            return tag.ToString();
        }
       
        //郵遞區號+鄉鎮市區的下拉選單
        public static string Residence(this HtmlHelper helper,string id,string name)
        {
            MyDataContext db =new MyDataContext();
            TagBuilder tag = new TagBuilder("select");
            tag.GenerateId(id);
            tag.MergeAttribute("name",name);
            foreach(var m in db.Regions){
                tag.InnerHtml += "<option class='sub_" + m.Region_縣市 + "' value='" 
		+ m.Residence_鄉鎮市區 + "'>" + m.Residence_鄉鎮市區 + "</option>";
            }
            return tag.ToString();
        }
    }

在View上利用Helper叫出來


<%=Html.Residence("Residence", "Residence")%>

順道一提,如果不想在每個View上都import一堆命名空間的話,可以再web.config中import常用的

命名空間,如下:

53647b3b1ba94be8914a8ee31ae2d617

完成了準備工作,先來看看還沒加上jQuery的成果

0197d7479bcd459a9a82d2ca20e4f2d2

就像上面的圖一樣,全部的鄉鎮縣市都跑出來了。

接下來進入今天的重點,jQuery!!

要寫之前要記得先加入載入jQuery的js檔

然後直接在View上加入以下的jQuery


        $(function () {
            makeRegion("Region", "Residence");
        });

        function makeRegion(parent, child) {
            $("body").append("<select style='display:none' id='" + parent + child + "'></select>");
            $("#" + parent + child).html($("#" + child + " option"));
            $("#" + child).html("<option value='0'>行政區</option>");
            $("#" + parent).change(function () {
                var AddAttr = $("#" + parent).attr("value");
                $("#" + child).html($("#" + parent + child + " .sub_" + AddAttr).clone());
                if (AddAttr == "0") {
                    $("#" + child).html("<select value='0'>行政區</select>");
                }
            });
        };
    
    </script>

2-4行是說當頁面載完之後,執行makeRegion(兩個參數) 這個function。$(function{ .... })是jQuery的

簡短寫法。意思跟$(document).ready(function(){…… }) 一樣

6-17行是這個funtion的主體,傳入兩個參數分別是parent跟child

第7行是指在body這個標籤下增加一個select的tag,這個tag是隱藏的,用來藏我們要的資訊

我們給這個tag的id是我們傳入的兩個參數相連,在本例子中就是 id=”RegionResidence”

第8行是我們在上面這個隱藏的tag底下,加入option,而option的來源,是我們一開始用helper建立

出來的鄉鎮市區下拉選單。

$("#"+child+” option”) 這段是jQuery的選擇器,意指抓id為child(child是參數,這邊傳入的是Residence)

底下所有的 option,在本例子中,就是所有的鄉鎮市區選單。

第9行是把一開始的地區下拉選單,設為行政區。

10-16行是指在地區的下拉選單被選擇時,會觸發change的事件,然後這個事件我們要執行一個function

第11行是把目前選到的地區的下拉選單的value的值,存到一個變數中

第12行跟第8行很像,就是把id為parent+child(兩個都是參數,就是抓我們隱藏的那個select)且class為

sub_加上選到的AddAttr的選項複製clone() 到鄉鎮市區的選單中。

13-15說明如果AddAttr等於0這個字串的話,就把鄉鎮市區的選單改為行政區。

完成之後的成果

934fa58e5f494f1fbaa4c517f78142ca 

呼,說明完了,不過jQuery不動手做做看的話,一定看不懂。

我也是看了demo大的文章,想了很久,在自己動手邊想邊打了三次,才把這個例子弄熟。

有興趣的可以動手做做看,還滿好玩的。

 

-----------------------------------------------------------------------------------------------------------------------------------------------

今天經過高人指點,發現上面的Code好像有點繞遠路的感覺。因此來修改一下。

首先,把產生鄉鎮市區的下拉選單的Helper改一下。


         public static string Residence(this HtmlHelper helper, string id, string name)
         {
             return Residence(helper, id, name, null);
         }
       
        //郵遞區號+鄉鎮市區的下拉選單
        //最後多加一個可以自訂屬性的參數
        public static string Residence(this HtmlHelper helper,string id,string name, object  htmlAttributes)
        {
            MyDataContext db =new MyDataContext();
            TagBuilder tag = new TagBuilder("select");
            tag.GenerateId(id);
            tag.MergeAttribute("name",name);
            tag.MergeAttributes(new RouteValueDictionary(htmlAttributes));
            foreach(var m in db.Regions){
                tag.InnerHtml += "<option class='sub_" + m.Region_縣市 + "' value='" 
                + m.Residence_鄉鎮市區 + "'>" + m.Residence_鄉鎮市區 + "</option>";
            }
            return tag.ToString();
        }

在View上改成:


<select id="Residence" name="Residence"><option value="0">行政區</option></select>
<%=Html.Residence("RegionResidence", "RegionResidence", new { style = "display:none" })%>

第一行一樣是地區的下拉選單

第二行是下拉選單,但是一開始只有"行政區"一個選擇

第三行是所有縣市區域的下拉選單,但是把它設為隱藏

改成這樣之後,jQuery的程式碼就大大的減少了


        $(function () {
            makeRegion("Region", "Residence");
        });

        function makeRegion(parent, child) {
            $("#" + parent).change(function () {
              var AddAttr = $("#" + parent).attr("value");
              $("#" + child).html($("#" + parent + child + " .sub_" + AddAttr).clone());
              if (AddAttr == "0") {
                    $("#" + child).html("<option value='0'>行政區</option>");
              }
            });
        };
    </script>

2-4行在頁面ready之後去呼叫一個function

6-14行是function主體

第7行再說當地區的下拉選單改變時,呼叫一個匿名的function

這個function做的第一件事,就是先把選到的地區欄位的value值存在AddAttr裡面

第9行是說把隱藏的所有鄉鎮市區的下拉選單中,所有Class符合AddAttr的option複製

到空白的下拉選單中

第10行做了一個判斷,如果AddAttr的value是0,也就是選到"請選擇縣市"的時候

將鄉鎮市區的option改為行政區。

就這樣,經高人指點之後,Code果然少了不少。