使用基于另一个下拉列表的MVC2填充下拉列表(级联DropDownList)

我正在制作一个处理车辆的应用程序。 我需要两个DropDownLists:

  • 制作:所有车辆制造
  • 模型:属于Make DropDownList的选定值的模型

如何在MVC2中完成?

我的想法:当我选择第一个列表时,是否使用ajax调用,然后将模型拉回到模型DDL? 模型绑定将如何发挥作用?

更新我发布了我最终做的答案。 它非常简单 ,效果很好。

如果你有这种倾向,你也可以使用get,但是你必须指定你想要这样… return Json(citiesList, JsonRequestBehavior.AllowGet);

这就是我最终做的……不需要额外的插件/ 1000行代码……

Html

 //The first DDL is being fed from a List in my ViewModel, You can change this... <%: Html.DropDownList("MakeList", new SelectList(Model.Makes, "ID", "Name")) %>  

JQuery

  $(document).ready(function () { $('#MakeList').change(function () { $.ajaxSetup({ cache: false }); var selectedItem = $(this).val(); if (selectedItem == "" || selectedItem == 0) { //Do nothing or hide...? } else { $.post('<%: ResolveUrl("~/Sell/GetModelsByMake/")%>' + $("#MakeList > option:selected").attr("value"), function (data) { var items = ""; $.each(data, function (i, data) { items += ""; }); $("#ModelID").html(items); $("#ModelID").removeAttr('disabled'); }); } }); }); 

那个行动

  [HttpPost] public ActionResult GetModelsByMake(int id) { Models.TheDataContext db = new Models.TheDataContext(); List models = db.Models.Where(p=>p.MakeID == id).ToList(); return Json(models); } 

这是一个很好的方法:

假设我们有两个下拉列表,国家和城市,默认情况下禁用城市下拉列表,当选择国家/地区时,会发生以下情况:

 1. city drop down list gets enabled. 2. An AJAX call is made to an action method with the selected country and a list of cities is returned. 3. the city drop down list is populated with the JSON data sent back. 

原始代码的积分由MVC Central提供给King Wilder 。 此示例是从他在Golf Tracker系列中的代码中提取的简化版本。

HTML

   

JavaScript的

 // Change event handler to the first drop down ( Country List ) $("#Country").change(function() { var countryVal = $(this).val(); var citySet = $("#City"); // Country need to be selected for City to be enabled and populated. if (countryVal.length > 0) { citySet.attr("disabled", false); adjustCityDropDown(); } else { citySet.attr("disabled", true); citySet.emptySelect(); } }); // Method used to populate the second drop down ( City List ) function adjustCityDropDown() { var countryVal = $("#Country").val(); var citySet = $("#City"); if (countryVal.length > 0) { // 1. Retrieve Cities that are in country ... // 2. OnSelect - enable city drop down list and retrieve data $.getJSON("/City/GetCities/" + countryVal , function(data) { // loadSelect - see Note 2 bellow citySet.loadSelect(data); }); } } 

行动方法

 [HttpGet] public ActionResult GetCities(string country) { Check.Require(!string.IsNullOrEmpty(country), "State is missing"); var query = // get the cities for the selected country. // Convert the results to a list of JsonSelectObjects to // be used easily later in the loadSelect Javascript method. List citiesList = new List(); foreach (var item in query) { citiesList.Add(new JsonSelectObject { value = item.ID.ToString(), caption = item.CityName }); } return Json(citiesList, JsonRequestBehavior.AllowGet); } 

重要笔记:

1.将结果转换为选项标记时, JsonSelectObject有助于JsonSelectObject因为它将在下面的javascript loadSelect方法中使用。 它基本上是一个具有两个属性值和标题的类:

 public class JsonSelectObject { public string value { get; set; } public string caption { get; set; } } 

2.函数loadSelect是一个辅助方法,它获取最初类型为JsonSelectObject的json对象列表,将其转换为要在调用下拉列表中注入的选项列表。 它是原始代码中引用的“jQuery In Action”一书中的一个很酷的技巧,它包含在你需要引用的jquery.jqia.selects.js文件中。 这是js文件中的代码:

 (function($) { $.fn.emptySelect = function() { return this.each(function() { if (this.tagName == 'SELECT') this.options.length = 0; }); } $.fn.loadSelect = function(optionsDataArray) { return this.emptySelect().each(function() { if (this.tagName == 'SELECT') { var selectElement = this; selectElement.add(new Option("[Select]", ""), null); $.each(optionsDataArray, function(index, optionData) { var option = new Option(optionData.caption, optionData.value); if ($.browser.msie) { selectElement.add(option); } else { selectElement.add(option, null); } }); } }); } })(jQuery); 

这种方法可能很复杂,但最后你会得到一个干净而紧凑的代码,你可以在其他地方使用它。

我希望这可以帮到你 ,,,


更新

在AJAX调用中使用POST而不是GET

您可以使用以下代码替换$.getJSON调用,以使用POST而不是GET进行ajax调用。

 $.post("/City/GetCities/", { country: countryVal }, function(data) { citySet.loadSelect(data); }); 

还记得通过使用[HttpPost]更改[HttpGet]注释来更改Action方法以接受POST请求,并在Action方法中返回结果时删除JsonRequestBehavior.AllowGet

重要的提示

请注意,我们使用的是所选项目的值而不是名称。 例如,如果用户选择了以下选项。

  

然后“美国”被发送到Action方法而不是“美国”

更新2:访问控制器中的选定值

假设您的Vehicle viewmodel中有以下两个属性:

 public string Maker { get; set; } public string Model { get; set; } 

并使用与ViewModel属性相同的名称命名select元素。

   

然后,所选值将自动绑定到ViewModel,您可以直接在Action Method中访问它们。

如果页面强烈键入到该ViewModel,这将起作用。


注意:对于第一个列表(The Makes List),您可以在ViewModel中创建一个类型为SelectList的MakersList,并使用HTML帮助程序自动使用ViewModel中的列表填充Makers Drop Down。 代码看起来像这样:

 <%= Html.DropDownListFor(model => model.Maker, Model.MakersList) %> 

在这种情况下,此选择的生成名称也将是“Maker”(ViewModel中属性的名称)。

我希望这是你正在寻找的答案。

最简单的方法是使用jQuery“cascade”插件。 http://plugins.jquery.com/project/cascade (查看那里的演示页面)。

如果你想使用ajax来解决价值,它也可以帮助你,并且它从前一个答案中消除了很多代码,所以你可以专注于你的逻辑:)

您可以在google中找到很多示例,但最终只能使用以下脚本:

 $('#myChildSelect').cascade('#myParentSelect', { ajax: '/my/url/action', template: function(item) { return ""; }, match: function(selectedValue) { return this.when == selectedValue; } });