摘要:【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,然後看著網頁讀來讀去的,現在這樣感覺清爽多了!但總覺得可以更簡單,更少一點的程式碼來達到這種效果,只要我繼續努力的話,哈,也請各位路過的前輩們,如果有那裡看不下去的地方,還請多多提點!!!