c# - ejemplos - dropdownlistfor mvc
La forma más sencilla de crear un menú desplegable en cascada en ASP.NET MVC 3 con C# (1)
Quiero crear dos DropDownList
en una cascada usando MVC3
(preferiblemente Razor
) con C#
.
Me gustaría tener un menú desplegable donde pueda elegir el año y otro donde pueda elegir un conjunto específico de meses dependiendo del año seleccionado.
Vamos a decirlo simple. Cuando elijo el año actual (es decir, 2011) en la lista desplegable "año", la lista desplegable "mes" se rellena con los meses hasta el mes actual (es decir, marzo). Para los otros casos (otros años) no se da ninguna restricción. Además, sería bueno "bloquear" la lista desplegable "mes" antes de seleccionar cualquier elemento en la lista desplegable "año".
Ya busqué en Internet algunas soluciones, usando jQuery
o incluso enfoques caseros, pero todas se refieren a versiones anteriores de MVC y algunos comandos están en desuso en MVC3
.
Como siempre, comienzas con un modelo:
public class MyViewModel
{
public int? Year { get; set; }
public int? Month { get; set; }
public IEnumerable<SelectListItem> Years
{
get
{
return Enumerable.Range(2000, 12).Select(x => new SelectListItem
{
Value = x.ToString(),
Text = x.ToString()
});
}
}
}
luego un controlador:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel();
return View(model);
}
public ActionResult Months(int year)
{
if (year == 2011)
{
return Json(
Enumerable.Range(1, 3).Select(x => new { value = x, text = x }),
JsonRequestBehavior.AllowGet
);
}
return Json(
Enumerable.Range(1, 12).Select(x => new { value = x, text = x }),
JsonRequestBehavior.AllowGet
);
}
}
y finalmente una vista:
@model AppName.Models.MyViewModel
@Html.DropDownListFor(
x => x.Year,
new SelectList(Model.Years, "Value", "Text"),
"-- select year --"
)
@Html.DropDownListFor(
x => x.Month,
Enumerable.Empty<SelectListItem>(),
"-- select month --"
)
<script type="text/javascript">
$(''#Year'').change(function () {
var selectedYear = $(this).val();
if (selectedYear != null && selectedYear != '''') {
$.getJSON(''@Url.Action("Months")'', { year: selectedYear }, function (months) {
var monthsSelect = $(''#Month'');
monthsSelect.empty();
$.each(months, function (index, month) {
monthsSelect.append($(''<option/>'', {
value: month.value,
text: month.text
}));
});
});
}
});
</script>
Obviamente notará que en mi ejemplo he codificado todos los valores. Debería mejorar esta lógica usando nociones como el año actual, el mes actual, probablemente incluso recuperar esos valores de un repositorio, etc ... pero para el propósito de la demostración esto debería ser suficiente para ponerlo en el camino correcto.