前言 平時工作中下拉聯動是相對比較麻煩的地方,雖然邏輯簡單,但是需要寫一堆js跟ajax請求。現在打算在.net core mvc下封裝一個下拉聯動組件方便使用。 下麵將實現一個 國家 語言 省市區 的多級聯動 創建實體模型 寫出對應下拉的Action方法 這裡 下拉contorler名稱約定為Dr ...
前言
平時工作中下拉聯動是相對比較麻煩的地方,雖然邏輯簡單,但是需要寫一堆js跟ajax請求。現在打算在.net core mvc下封裝一個下拉聯動組件方便使用。
下麵將實現一個 國家 語言 省市區 的多級聯動
創建實體模型
1 public class UserModel 2 { 3 /// <summary> 4 /// 用戶名 5 /// </summary> 6 public string UserName { get; set; } 7 8 9 /// <summary> 10 /// 國家 11 /// </summary> 12 public int CountryId { get; set; } 13 14 /// <summary> 15 /// 語言 16 /// </summary> 17 public int LanguageId { get; set; } 18 19 /// <summary> 20 ///省 21 /// </summary> 22 public int PronviceId { get; set; } 23 24 /// <summary> 25 /// 市 26 /// </summary> 27 public int CityId { get; set; } 28 29 /// <summary> 30 /// 區 31 /// </summary> 32 public int GetDistrictId { get; set; } 33 34 } 35 36 public class Area 37 { 38 public int Id { get; set; } 39 40 public string Name { get; set; } 41 42 public int? ParentId { get; set; } 43 } 44 45 public class Language 46 { 47 public int Id { get; set; } 48 49 public int CountryId { get; set; } 50 51 public string Name { get; set; } 52 }
寫出對應下拉的Action方法
這裡 下拉contorler名稱約定為DropdownListController,Action名稱約定為 Get +欄位名的方式,參數名稱約定使用 父級欄位的名稱。這樣在前臺頁面就不用指定獲取數據源的url了
1 public class DropdownListController : Controller 2 { 3 private List<Area> areas; 4 5 private List<Language> languages; 6 7 public DropdownListController() 8 { 9 areas = new List<Area> 10 { 11 new Area { Id = 1, Name = "中國", ParentId = null }, 12 new Area { Id = 2, Name = "美國", ParentId = null }, 13 new Area { Id = 3, Name = "江蘇省", ParentId = 1 }, 14 new Area { Id = 4, Name = "浙江省", ParentId = 1 }, 15 new Area { Id = 5, Name = "紐約州", ParentId = 2 }, 16 new Area { Id = 6, Name = "南京市", ParentId = 3 }, 17 new Area { Id = 7, Name = "杭州市", ParentId = 4 }, 18 new Area { Id = 8, Name = "紐約市", ParentId = 5 }, 19 new Area { Id = 9, Name = "曼哈頓區", ParentId = 8 }, 20 new Area { Id = 10, Name = "老廟區", ParentId = 6 }, 21 new Area { Id = 11, Name = "西湖區", ParentId = 7 } 22 }; 23 24 languages = new List<Language> 25 { 26 new Language{ Id=1,CountryId=1, Name="簡體中文" }, 27 new Language{ Id=2,CountryId=2, Name="美式英語"}, 28 }; 29 } 30 31 public IActionResult GetCountryId() 32 { 33 return Json(areas.FindAll(x => x.ParentId == null).Select(x => new { value = x.Id, text = x.Name })); 34 } 35 36 public IActionResult GetLanguageId(int countryId) 37 { 38 return Json(languages.FindAll(x => x.CountryId == countryId).Select(x => new { value = x.Id, text = x.Name })); 39 } 40 41 public IActionResult GetPronviceId(int countryId) 42 { 43 return Json(areas.FindAll(x => x.ParentId == countryId).Select(x => new { value = x.Id, text = x.Name })); 44 } 45 46 public IActionResult GetCityId(int pronviceId) 47 { 48 return Json(areas.FindAll(x => x.ParentId == pronviceId).Select(x => new { value = x.Id, text = x.Name })); 49 } 50 51 public IActionResult GetDistrictId(int cityId) 52 { 53 return Json(areas.FindAll(x => x.ParentId == cityId).Select(x => new { value = x.Id, text = x.Name })); 54 } 55 }
前臺Html
引用了 bootstrap, jquery
@model UserModel <a asp-action="Edit" class="btn btn-success m-b-15">去編輯頁</a> <div class="form-inline row"> <div class="form-group "> <label>國家</label> <select asp-for="CountryId" class="form-control" asp-items="ViewBag.CountryList" data-select-childids="LanguageId,PronviceId"> <option value="">請選擇</option> </select> </div> <div class="form-group "> <label>語言</label> <select asp-for="LanguageId" class="form-control"> <option value="">請選擇</option> </select> </div> <div class="form-group"> <label>省</label> <select asp-for="PronviceId" class="form-control" data-select-childids="CityId"> <option value="">請選擇</option> </select> </div> <div class="form-group"> <label>市</label> <select asp-for="CityId" class="form-control" data-select-childids="DistrictId"> <option value="">請選擇</option> </select> </div> <div class="form-group"> <label>區</label> <select asp-for="DistrictId" class="form-control"> <option value="">請選擇</option> </select> </div> </div>
下拉聯動的js,基於 jquery
$(function () { //下拉聯動初始化 $('select[data-select-childids]').each(function () { getChildSelect($(this).attr("id"), true); }); //下拉聯動 data-select-childids 填寫聯動的Id,data-select-url 數據請求路徑,data-select-paramids 追加的參數,data-select-value 當前值 $('select[data-select-childids]').change(function (e) { getChildSelect($(this).attr("id")); }); //清空下拉聯動子選擇項 function getChildSelect(selectid, isInit) { var select = $('#' + selectid); var selectchildIds = select.data('select-childids'); if (!selectchildIds) return; var childIds = selectchildIds.split(',') for (var i = 0; i < childIds.length; i++) { if (!childIds[i]) continue; var child = $('#' + childIds[i]); var childValue = child.val(); if (!childValue) childValue = child.data("select-value"); child.empty(); //預設值設定 var hasdefault = child.data("select-hasdefault"); if (hasdefault != "false") { child.append('<option value="">請選擇</option>'); } //父級下拉有值時,ajax獲取數據 if (select.val()) {var url = child.data('select-url') ? child.data('select-url') : '/DropdownList/Get' + child.attr("id");//url預設值 var verb = child.data('verb') ? child.data('verb') : 'GET';//請求的方法 var paramObj = {};//追加參數 getParentSelectParam(selectid, paramObj) //追加控制參數 var paramids = child.data('select-paramids'); if (paramids) { var paramidsArr = paramids.split(',') for (var k = 0; k < paramidsArr.length; k++) { paramObj[paramidsArr[k]] = $('#' + paramidsArr[k]).val(); } } $.ajax({ type: verb, url: url, data: paramObj, async: false, contentype: "application/x-www-form-urlencoded; charset=UTF-8", success: function (data) { if (data) { for (var j = 0; j < data.length; j++) { var selected = data[j].value == childValue ? 'selected = "selected"' : ''; child.append('<option value="' + data[j].value + '" ' + selected + '>' + data[j].text + '</option>'); } } } }); } //子級下拉如果還有下級,非初始化的時候 遞歸 if (!isInit && child.data('select-childids')) getChildSelect(child.attr("id")); } } //遞歸獲取父級選中的值 param追加的url參數 function getParentSelectParam(selectid, param) { var select = $("#" + selectid); param[selectid] = $(select).val(); $('select[data-select-childids]').each(function () { var id = $(this).attr("id"); if (selectid != id) { var childids = $(this).data('select-childids'); if (childids) { childidsArr = childids.split(','); for (var i = 0; i < childidsArr.length; i++) { if (childidsArr[i] == selectid) { getParentSelectParam(id, param);//繼續向父級查找 } } } } }); } });
後臺 action
public class HomeController : Controller { private List<Area> areas; public HomeController() { areas = new List<Area> { new Area { Id = 1, Name = "中國", ParentId = null }, new Area { Id = 2, Name = "美國", ParentId = null }, new Area { Id = 3, Name = "江蘇省", ParentId = 1 }, new Area { Id = 4, Name = "浙江省", ParentId = 1 }, new Area { Id = 5, Name = "紐約州", ParentId = 2 }, new Area { Id = 6, Name = "南京市", ParentId = 3 }, new Area { Id = 7, Name = "杭州市", ParentId = 4 }, new Area { Id = 8, Name = "紐約市", ParentId = 5 }, new Area { Id = 9, Name = "曼哈頓區", ParentId = 8 }, new Area { Id = 10, Name = "老廟區", ParentId = 6 }, new Area { Id = 11, Name = "西湖區", ParentId = 7 } }; } public IActionResult Index() { ViewBag.CountryList = areas.FindAll(x => x.ParentId == null).Select(x => new SelectListItem { Value = x.Id.ToString(), Text = x.Name }); return View(new UserModel()); } public IActionResult Edit() { ViewBag.CountryList = areas.FindAll(x => x.ParentId == null).Select(x => new SelectListItem { Value = x.Id.ToString(), Text = x.Name }); return View(new UserModel() { CountryId = 2, PronviceId = 5, CityId=8,DistrictId = 9, LanguageId = 2 }); } }
運行效果
用法說明
<a asp-action="Index" class="btn btn-success m-b-15">返回</a> <br /><br /> <div class="form-inline row"> <div class="form-group "> <label>國家</label> <select asp-for="CountryId" class="form-control selectList" asp-items="ViewBag.CountryList" data-select-childids="LanguageId,PronviceId"> <option value="">請選擇</option> </select> </div> <div class="form-group "> <label>語言</label> <select asp-for="LanguageId" class="form-control" data-select-value="@Model.LanguageId" data-select-url="/DropDownList/GetLanguageId?id=1" data-select-paramids="CountryId" data-select-hasdefault="false" data-verb="Get" 請求的方式 > <option value="">請選擇</option> </select> </div> <div class="form-group"> <label>省</label> <select asp-for="PronviceId" class="form-control" data-select-childids="CityId" data-select-value="@Model.PronviceId" data-select-url="/DropDownList/GetPronviceId?id=1" data-select-paramids="CountryId" > <option value="">請選擇</option> </select> </div> <div class="form-group"> <label>市</label> <select asp-for="CityId" class="form-control" data-select-childids="DistrictId" data-select-value="@Model.CityId" data-select-url="/DropDownList/GetCityId" data-select-paramids="PronviceId" > <option value="">請選擇</option> </select> </div> <div class="form-group"> <label>區</label> <select asp-for="DistrictId" class="form-control" data-select-value="@Model.DistrictId" data-select-url="/DropDownList/GetDistrictId" > <option value="">請選擇</option> </select> </div> </div>
data-select-childids :設置聯動的select下拉的Id逗號分隔。例如在國家的下拉中 data-select-childids="LanguageId,PronviceId"表示,國家的下拉影響 語言和 省
data-select-value: 數據載入時的初始值 用在編輯表單時,存儲當前下拉
data-select-url: 請求的url
data-select-paramids: 參數值的Id