jquery - Cómo crear una lista desplegable en cascada
asp.net asp.net-mvc (1)
Tengo dos listas desplegables para fines de filtrado. ¿Cómo puedo cambiar esta lista desplegable a catchcadaing dropdownlist?
public ActionResult Index()
{
REFINED_DBEntities db = new REFINED_DBEntities();
ViewBag.Subdivision =
new SelectList(db.Retention_Model_Predictions_DS_Manual.Select(m => m.Subdivision).Distinct().OrderBy(c=>c.ToUpper()),
"Subdivision");
ViewBag.UnderwriterName =
new SelectList(db.Retention_Model_Predictions_DS_Manual.Select(m => m.Underwriter_Name).Distinct(),
"Underwriter_Name");
return View();
}
Vista HTML
<div class="form-group ">
@Html.DropDownList("Subdivision", (IEnumerable<SelectListItem>)ViewBag.Subdivision, "Select Region", new { @class = "form-control", @id = "subDivision" })
</div>
<div class="form-group ">
@Html.DropDownList("Underwriter_Name", (IEnumerable<SelectListItem>)ViewBag.UnderwriterName, "Select Underwriter", new { @class = "form-control", @id = "uwriter" })
</div>
La idea del menú desplegable en cascada es que selecciona un valor en el primer menú desplegable y activa algunas acciones para cargar las opciones para un segundo menú desplegable. Un ejemplo clásico es el menú desplegable País y el menú desplegable Estado. Cada vez que el usuario selecciona un país, el menú desplegable del país debe actualizarse con los estados de ese país.
Le voy a dar un ejemplo muy genérico del caso de uso País-Estado. Puede usar los mismos conceptos para construir su caso de uso específico
Para empezar, cree un modelo de vista para su vista.
Cree una propiedad de tipo
List<SelectListItem>
para pasar la lista de opciones necesarias para crear el elemento SELECT y otra propiedad para almacenar el valor de la opción seleccionada.
Haremos esto para los dos elementos SELECT.
public class CreateUserVm
{
public List<SelectListItem> Countries { set;get;}
public int SelectedCountryId { set;get;}
public List<SelectListItem> States { set;get;}
public int SelectedStateId { set;get;}
public CreateUserVm()
{
this.Countries = new List<SelectListItem>();
this.States = new List<SelectListItem>();
}
}
Ahora en su método de acción GET, cree un objeto de este modelo de vista, inicialice las opciones para el primer menú desplegable, en este caso, la propiedad
Countries
y envíelo a la vista.
public ActionResult Create()
{
var vm=new CreateUserVm();
vm.Countries = GetCountries();
return View(vm);
}
private List<SelectListItem> GetCountries()
{
var list = new List<SelectListItem>
{
new SelectListItem() {Value = "1", Text = "USA"},
new SelectListItem() {Value = "2", Text = "India"},
};
return list;
}
Ahora en su Vista, que está fuertemente escrita en nuestro modelo de vista.
utilizaremos el método auxiliar
DropDownListFor
para representar los menús desplegables
@model CreateUserVm
@using (Html.BeginForm("Index", "Home"))
{
@Html.DropDownListFor(a=>a.SelectedCountryId,Model.Countries,"Select one")
@Html.DropDownListFor(a => a.SelectedStateId, Model.States, "Select one",
new { data_url = Url.Action("GetStates") })
<input type="Submit" />
}
Esto generará 2 menús desplegables, uno con opciones de
Country
y el segundo estará vacío (porque no cargamos nada en la propiedad de los
States
).
Ahora tendremos algunos javascript (estamos usando jquery aquí para una fácil manipulación DOM) que escuchará el evento de
change
del primer menú desplegable (País), leerá el valor seleccionado y realizará una llamada ajax al método
GetStates
y
GetStates
el Valor de opción de país seleccionado.
Puede ver que configuré un atributo de datos html5 para el segundo menú desplegable donde estoy almacenando la url para el método
GetStates
.
Entonces, en mi javascript, simplemente puedo leer este valor de atributo de datos y hacer una llamada a esa url para obtener los datos.
$(function () {
$("#SelectedCountryId").change(function () {
var v = $(this).val();
var url = $("#SelectedStateId").data("url") + ''?countryId='' + v;
var $states = $("#SelectedStateId");
$.getJSON(url, function (states) {
$states.empty();
$.each(states, function (i, item) {
$states.append($("<option>").text(item.Text).val(item.Value));
});
});
});
});
Ahora, agreguemos un método de acción
GetStates
que acepte
countryId
y devuelva los estados para ese país en una lista de
SelectListItem
como matriz JSON.
public ActionResult GetStates(int countryId)
{
var states = new List<SelectListItem>();
if (countryId == 1)
{
states.Add(new SelectListItem() {Value = "101", Text = "Michigan"});
states.Add(new SelectListItem() { Value = "102", Text = "New York" });
}
else if (countryId == 2)
{
states.Add(new SelectListItem() { Value = "103", Text = "Kerala" });
states.Add(new SelectListItem() { Value = "104", Text = "Goa" });
}
return Json(states, JsonRequestBehavior.AllowGet);
}
Aquí he codificado los países y estados. Pero si tiene una base de datos que tiene estos datos, reemplace los valores codificados con datos de sus tablas.
Cuando está editando un registro, todo lo que tiene que hacer es cargar la propiedad
States
en la acción GET en función del CountryId que se guarda.