Para implementar listas desplegables en cascada que admitan la validación y encuadernación integradas de MVC, tendrá que hacer algo un poco diferente de lo que se hace en las otras respuestas aquí.
Si su modelo tiene validación, esto lo admitirá.Un extracto de un modelo con la validación:
[Required]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public Guid cityId { get; set; }
En su controlador es necesario agregar un método get, para que su vista será capaz de obtener los datos relevantes más tarde:
[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);
}
Ahora, a la opinión de que he mencionado anteriormente:
En su opinión que tiene dos menús desplegables similares a esta:
<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>
El contenido de los menús desplegables está vinculado por el controlador y se completa automáticamente. Nota: en mi experiencia al eliminar este enlace y confiar en el script java para rellenar los menús desplegables, pierdes la validación. Además, la forma en que estamos vinculados aquí juega bien con la validación, por lo que no hay ninguna razón para cambiarla.
Ahora en nuestro plugin 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));
Puede copiar lo anterior jQuery que he creado, en <script>...</script>
etiquetas en su opinión, o en un archivo de secuencia de comandos independiente si así lo desea (Nota I Actualizado esto para hacer se cruza el navegador, sin embargo, el escenario en el que estaba usando ya no es necesario, sin embargo debería funcionar).
En esas mismas etiquetas de script, (no en un archivo separado) se puede llamar el plugin utilizando el siguiente javascript:
$(document).ready(function() {
var primaryDropDown = document.getElementById('stateId');
var secondaryDropdown = document.getElementById('cityId');
var actionUrl = '@Url.Action("GetData")'
$(primaryDropDown).cascade(secondaryDropdown, actionUrl);
});
recuerde añadir la parte $(document).ready
, la página debe estar completamente cargada antes Intenta hacer que los drop downs entren en cascada.
Mi Blog en cascada DropDownList en ASP.Net MVC (http://blogs.msdn.com/b/ rickandy/archive/2012/01/09/cascasding-dropdownlist-in-asp-net-mvc.aspx) hace esto exactamente. Véase también mi tutorial Cómo trabajar con DropDownList Box y jQuery (http://www.asp.net/mvc/tutorials/javascript/working-with-the-dropdownlist-box-and-jquery/using-the-dropdownlist-helper- with-aspnet-mvc) – RickAndMSFT