Чтобы реализовать каскадные выпадающие списки, которые поддерживают встроенную проверку и привязку MVC, вам нужно будет сделать что-то немного отличное от того, что сделано в других ответах здесь.
Если ваша модель имеет проверку, этоподдержит это.Выдержка из модели с проверкой:
[Required]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public Guid cityId { get; set; }
В вашем контроллере вам нужно добавить метод get, чтобы ваше представление могло получить соответствующие данные позже:
[AcceptVerbs(HttpVerbs.Get)]
public JsonResult GetData(Guid id)
{
var cityList = (from s in db.City where s.stateId == id select new { cityId = s.cityId, name = s.name });
//simply grabbing all of the cities that are in the selected state
return Json(cityList.ToList(), JsonRequestBehavior.AllowGet);
}
Теперь к представлению, которое я упоминал ранее:
По вашему мнению, у вас есть два раскрывающихся списка, подобных этому:
<div class="editor-label">
@Html.LabelFor(model => model.stateId, "State")
</div>
<div class="editor-field">
@Html.DropDownList("stateId", String.Empty)
@Html.ValidationMessageFor(model => model.stateId)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.cityId, "City")
</div>
<div class="editor-field">
@*<select id="cityId"></select>*@
@Html.DropDownList("cityId", String.Empty)
@Html.ValidationMessageFor(model => model.cityId)
</div>
Содержимое в раскрывающихся списках ограничено контроллером,и автоматически заполняются.Примечание: по моему опыту, удаление этой привязки и использование java-скрипта для заполнения выпадающих списков приводит к потере проверки.Кроме того, способ привязки здесь хорошо сочетается с проверкой, поэтому нет оснований для ее изменения.
Теперь на наш плагин jQuery:
(function ($) {
$.fn.cascade = function (secondaryDropDown, actionUrl, stringValueToCompare) {
primaryDropDown = this; //This doesn't necessarily need to be global
globalOptions = new Array(); //This doesn't necessarily need to be global
for (var i = 0; i < secondaryDropDown.options.length; i++) {
globalOptions.push(secondaryDropDown.options[i]);
}
$(primaryDropDown).change(function () {
if ($(primaryDropDown).val() != "") {
$(secondaryDropDown).prop('disabled', false); //Enable the second dropdown if we have an acceptable value
$.ajax({
url: actionUrl,
type: 'GET',
cache: false,
data: { id: $(primaryDropDown).val() },
success: function (result) {
$(secondaryDropDown).empty() //Empty the dropdown so we can re-populate it
var dynamicData = new Array();
for (count = 0; count < result.length; count++) {
dynamicData.push(result[count][stringValueToCompare]);
}
//allow the empty option so the second dropdown will not look odd when empty
dynamicData.push(globalOptions[0].value);
for (var i = 0; i < dynamicData.length; i++) {
for (var j = 0; j < globalOptions.length; j++) {
if (dynamicData[i] == globalOptions[j].value) {
$(secondaryDropDown).append(globalOptions[j]);
break;
}
}
}
},
dataType: 'json',
error: function () { console.log("Error retrieving cascading dropdown data from " + actionUrl); }
});
}
else {
$(secondaryDropDown).prop('disabled', true);
}
secondaryDropDown.selectedindex = 0; //this prevents a previous selection from sticking
});
$(primaryDropDown).change();
};
} (jQuery));
Вы можете скопировать вышеупомянутый jQuery, которыйя создал теги <script>...</script>
в вашем представлении или, если хотите, в отдельном файле сценария (обратите внимание, я обновил его, чтобы сделать его кросс-браузерным, однако сценарий, в котором я использовал, больше не требуется, однако он должен работать),
В тех же тегах скрипта (не в отдельном файле) вы можете вызвать плагин, используя следующий javascript:
$(document).ready(function () {
var primaryDropDown = document.getElementById('stateId');
var secondaryDropdown = document.getElementById('cityId');
var actionUrl = '@Url.Action("GetData")'
$(primaryDropDown).cascade(secondaryDropdown, actionUrl);
});
Не забудьте добавить часть $(document).ready
, страницудолжен быть полностью загружен, прежде чем вы попытаетесь сделать каскад выпадающих.