web-dev-qa-db-fra.com

Moyen le plus simple de créer une liste déroulante en cascade dans ASP.NET MVC 3 avec C #

Je veux créer deux DropDownList dans un cascade en utilisant MVC3 (de préférence Razor) avec C#.

J'aimerais avoir une liste déroulante où vous pouvez choisir l'année et une autre où vous pouvez choisir un ensemble spécifique de mois en fonction de l'année sélectionnée.

Disons les choses simplement. Lorsque je choisis l'année en cours (c'est-à-dire 2011) dans la liste déroulante "année", la liste déroulante "mois" est remplie avec les mois jusqu'au mois en cours (c'est-à-dire mars). Pour les autres cas (autres années) aucune restriction n'est donnée. De plus, il serait bien de "bloquer" la liste déroulante "mois" avant de sélectionner un élément de la liste déroulante "année".

J'ai déjà cherché sur Internet des solutions, en utilisant jQuery ou même des approches maison, mais elles se réfèrent toutes à des versions antérieures de MVC et certaines commandes sont déconseillées dans MVC3.

69
CiccioMiami

Comme toujours, vous commencez avec un modèle:

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()
            });
        }
    }
}

puis un contrôleur:

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
        );
    }
}

et enfin une vue:

@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>

De toute évidence, vous remarquerez que dans mon exemple, j'ai codé en dur toutes les valeurs. Vous devriez améliorer cette logique en utilisant des notions comme l'année en cours, le mois en cours, probablement même récupérer ces valeurs dans un référentiel, etc ... mais aux fins de la démonstration, cela devrait être suffisant pour vous mettre sur la bonne voie.

140
Darin Dimitrov