【Jquery】連動式下拉選單 縣市/鄉鎮區

  • 9623
  • 0

摘要:【Jquery】連動式下拉選單 縣市/鄉鎮區

這篇想要紀錄的是,如何做出連動式的下拉選單,並且利用AJAX的技術,我想網路上的範例已經非常非常多,各種表現方式都有,但我這裡紀錄的是用我自己的想法去做,所以可能很鳥,可能很沒效率,也一定會有比我更好的方法,但既然是做紀錄,就當作是一個成長的過程,到時候回頭再來看,說不定還可以見證自己長大的過程(?)

前面廢話這麼多,該是切入主題了,因為學會怎麼使用Jquery的$.ajax,一夕之間,感覺甚麼事情都可以做了,因為縣市鄉鎮區的連動式下拉選單,在小弟任職的公司裡,用的是非常之多,所以乾脆自己建一個資料庫,ciry資料表裡放縣市,並且給一個獨立的ID值,另一個zone的資料表有兩個欄位,一個就放各縣市的鄉鎮區,另一個欄位放的是對應到的縣市ID,這樣就可以利用縣市的ID直接找到對應的鄉鎮區,以後有要修改很比較方便(例如五都合併)

資料庫設定完以後,再來就是重頭戲的部分了,我這邊是利用泛型處理常式處理select資料庫部分,其實裡面的程式碼就跟平常怎麼跟資料庫要資料一樣,所以部分的程式碼就省略,只著重在重點部分,如下

select.ashx.cs


public void ProcessRequest(HttpContext context)
        {
            if ((string)context.Request["cityorzone"] != null)
            {
                //這裡表示第一次進入網頁取縣市與鄉鎮區
                if ((string)context.Request["cityorzone"] == "c")
                {
                    DataTable Dt = new DataTable();
                    DataTable Dt2 = new DataTable();
                    //縣市id
                    string id = "";
                    //縣市名稱
                    string city = "";
                    //鄉鎮區名稱
                    string zone = "";
                    //取得縣市table,selectcity()裡面就自行發揮
                    Dt = selectcity();
                    //會取Rows[0]的資料是因為我想顯示的是第一筆city對應的鄉鎮區
                    Dt2 = selectzone(Dt.Rows[0]["id"].ToString());
                    //這裡是將縣市與id取出並加到變數中,並且用","區隔
                    for (int i = 0; i < Dt.Rows.Count; i++)
                    {
                        if (i != 0)
                        {
                            id += ",";
                            city += ",";
                        }
                        id += Dt.Rows[i]["id"].ToString();
                        city += Dt.Rows[i]["city"].ToString();                                                
                    }
                    //這裡是將鄉鎮區取出並加到變數中,並且用","區隔 我預設是抓台北的鄉鎮區
                    for (int j = 0; j < Dt2.Rows.Count; j++)
                    {
                        if (j != 0)
                        {
                            zone += ",";
                        }
                        zone += Dt2.Rows[j]["zone"].ToString();                                                
                    }
                    //最後回傳到前端再用"|"區隔,例如:1,2,3...|台北市,基隆市,新北市....|中正區,內湖區,信義區....
                    context.Response.Write(id + "|" + city + "|" + zone);
                }
                //這裡表示依照縣市去變換鄉鎮區,所以當使用者變換縣市時是來這邊重新select鄉鎮區
                else
                {
                    DataTable Dt = new DataTable();
                    string c_id = (string)context.Request["cityorzone"].ToString();
                    string zone = "";
                    Dt = selectzone(c_id);
                    for (int i = 0; i < Dt.Rows.Count; i++)
                    {
                        if (i != 0)
                        {
                            zone += ",";
                        }
                        zone += Dt.Rows[i]["zone"].ToString();
                    }
                    context.Response.Write(zone);
                }
            }            
        }

程式碼是有點複雜沒錯...,但其實是因為我想要進入網頁以後,再下拉選單那邊就有預設的值可以下拉,所以我才會分兩個動作,一個是預設的下拉選單,也就是cityorzone=c那塊,另一個就是當使用者變動city以後zone要重新取值所用的程式碼,也就是cityorzone!=c,而我這邊是用逗號和"|"來分隔每一個下拉選單的值,到時候在前端用split來分割字串,jquery的程式碼如下


           //傳給server的值,告訴server我這是第一次進入網頁時的狀態
           var citys = [{ name: "cityorzone", value: "c"}];
            //先移除下拉選單裡面的值,並免重整或產生接龍情況
            $("#ddlcity option").remove();
            $("#ddlzone option").remove();
            //都先加入提示的字串
            $("#ddlcity").append($("").attr("value", 0).text("請選擇縣市"));
            $("#ddlzone").append($("").attr("value", 0).text("請選擇鄉鎮區"));            
            $.ajax({
                type: "POST",
                url: "select.ashx",
                data: citys,
                dataType: "text",
                success: function(data) {
                    //取出來的值會長這樣1,2,3...|台北市,基隆市,新北市....|中正區,內湖區,信義區....
                    //做分割
                    var str = data.split("|");
                    var str_id = str[0].split(",");
                    var str_city = str[1].split(",");
                    var str_zone = str[2].split(",");                    
                    for (var i = 0; i < str_id.length; i++) {
                        //縣市
                        $("#ddlcity").append($("").attr("value", str_id[i]).text(str_city[i]));
                    }
                    for (var j = 0; j < str_zone.length; j++) {
                        //鄉鎮區
                        $("#ddlzone").append($("").attr("value", str_zone[j]).text(str_zone[j]));
                    }
                }
            });

有沒有感覺很"搞剛",但就對我而言就是個進步,接著是當city的下拉選單改變時,zone怎麼重新取值


 $("#ddlcity").change(function() {
            var city_id = $("#ddlcity option:selected").val();
            if (city_id != "0") {
                $("#ddlzone option").remove();
                $("#ddlzone").append($("").attr("value", 0).text("請選擇鄉鎮區"));
                if (city_id != "5" && city_id != "12") {
                    var city = $("#ddlcity option:selected").val();
                    var citys = [{ name: "cityorzone", value: city}];
                    $.ajax({
                        type: "POST",
                        url: "select.ashx",
                        data: citys,
                        dataType: "text",
                        success: function(data) {
                            var str_zone = data.split(",");
                            for (var i = 0; i < str_zone.length; i++) {
                                $("#ddlzone").append($("").attr("value", str_zone[i]).text(str_zone[i]));
                            }
                        }
                    });
                }
            }
        });

其實大同小異,差別在於cityorzone不再是c而是city,等於告訴server我這次只要取相對應的zone回來就好!,然後city_id那邊5和12是因為,在郵局那邊規範是,新竹市和嘉義市並沒有鄉鎮區,所以就不用加option上去

其實學會這樣子做連棟式下拉選單以後,就可以丟掉以前AutoPostBack,然後看著網頁讀來讀去的,現在這樣感覺清爽多了!但總覺得可以更簡單,更少一點的程式碼來達到這種效果,只要我繼續努力的話,哈,也請各位路過的前輩們,如果有那裡看不下去的地方,還請多多提點!!!