ASP.NET MVC 3中用C#创建级联下拉框的最简单方法

68

我想在使用MVC3(最好是Razor)和C#的过程中,创建两个 DropDownList,并以级联的形式进行连接。

我想要一个下拉列表,可以选择年份,另一个下拉列表则根据所选年份选择特定集合的月份。

简单来说,当我在下拉列表“年份”中选择当前年份(即2011年)时,“月份”下拉列表会填充至当前月份(即3月)。对于其他情况(其他年份),没有限制。此外,在选择下拉列表“年份”中的任何元素之前,“月份”下拉列表最好被“锁定”。

我已经在互联网上寻找了一些解决方案,使用了jQuery甚至自己编写的方法,但它们都涉及旧版本的 MVC,而且一些命令在MVC3中已经过时。

1个回答

139

像往常一样,您从一个模型开始:

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

然后是一个控制器:

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

最后是一个视图:

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

显然,你会注意到在我的例子中我已经硬编码了所有的值。你应该通过使用当前年份、当前月份等概念来改进这个逻辑,可能甚至从存储库中获取这些值等等...但为了演示的目的,这应该足以让你走上正确的轨道。


3
@Francesco,是的,你需要使用jQuery。 - Darin Dimitrov
1
这个<option/>是什么意思?我不明白。 - Roberto Bonini
1
Roberto Bonini,<option />是selectlistitem。它被附加在列表元素内部。 - Shawn Mclean
非常好!唯一需要改进的是恢复“-- 选择月份 --”标签。它最初被加载,但在monthsSelect.empty();中被删除。 - Stan Bashtavenko
一个真正有效的简单示例。Darin,你能解释一下为什么我们必须在<option>前面添加$吗?我知道$使它成为jquery元素..我以为它应该可以不用$就能工作...你能稍微解释一下吗..谢谢。monthsSelect.append($('<option/>', { value: month.value, text: month.text })); - Sugar Bowl
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接