Вот хороший способ сделать это:
Предположим, что у нас есть два раскрывающихся списка, страна и город, раскрывающийся список городов по умолчанию отключен, и при выборе страны происходит следующее:
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.
Кредиты за оригинальный код отправляются на King Wilder из MVC Central . Этот пример является упрощенной версией, извлеченной из его кода в серии Golf Tracker .
.
HTML
<select id="Country">
// a List of Countries Options Goes Here.
</select></div>
<select id="City" name="City" disabled="disabled">
// To be populated by an ajax call
</select>
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<JsonSelectObject> citiesList = new List<JsonSelectObject>();
foreach (var item in query)
{
citiesList.Add(new JsonSelectObject { value = item.ID.ToString(),
caption = item.CityName });
}
return Json(citiesList, JsonRequestBehavior.AllowGet);
}
Важные примечания:
1. JsonSelectObject
помогает упростить процесс преобразования результатов в тег опции, так как он будет использоваться в методе javascript loadSelect
ниже.
в основном это класс со значением и заголовком двух свойств:
public class JsonSelectObject
{
public string value { get; set; }
public string caption { get; set; }
}
2. Функция loadSelect
- это вспомогательный метод, который принимает список объектов json, изначально принадлежащих к типу JsonSelectObject
, и преобразует его в список параметров, которые будут добавлены в раскрывающийся список вызовов. Это классный трюк из книги «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);
Этот метод может быть сложным ,,, но в конце у вас будет чистый и компактный код, который вы сможете использовать везде.
Надеюсь, это было полезно ,,,
Обновление
Использование POST вместо GET в вызове AJAX
Вы можете заменить вызов $.getJSON
следующим кодом, чтобы сделать вызов ajax с использованием POST вместо GET.
$.post("/City/GetCities/", { country: countryVal }, function(data) {
citySet.loadSelect(data);
});
также не забудьте изменить метод Action для приема запросов POST, изменив аннотацию [HttpGet] с помощью [HttpPost] и удалив JsonRequestBehavior.AllowGet
при возврате результата в метод действия.
Важное примечание
Обратите внимание, что мы используем значение выбранного элемента, а не имя. например, если пользователь выбрал следующую опцию.
<option value="US">United States</option>
тогда «US» отправляется методу Action, а не «United States»
Обновление 2: доступ к выбранным значениям в контроллере
предположим, что в вашей Vehicle
viewmodel есть следующие два свойства:
public string Maker { get; set; }
public string Model { get; set; }
и вы называете выбранные элементы тем же именем, что и свойства ViewModel.
<select id="Maker" name="Maker">
// a List of Countries Options Goes Here.
</select></div>
<select id="Model" name="Model" disabled="disabled">
// To be populated by an ajax call
</select>
Тогда выбранные значения будут автоматически привязаны к вашей ViewModel, и вы сможете получить к ним доступ непосредственно в вашем методе действия.
Это будет работать, если страница строго типизирована для этой ViewModel.
Примечание. Для первого списка (The Makes List) вы можете создать MakersList типа SelectList в вашей ViewModel и использовать помощник HTML, чтобы автоматически заполнить ваш Makers Drop Down списком в вашей ViewModel. код будет выглядеть примерно так:
<%= Html.DropDownListFor(model => model.Maker, Model.MakersList) %>
В этом случае сгенерированное имя для этого выбора также будет «Создатель» (имя свойства в ViewModel).
Я надеюсь, что это ответ, который вы ищете.