如何在ASP.Net Core MVC中创建级联SelectList [英] How to create a cascading SelectList in ASP.Net Core MVC

查看:1068
本文介绍了如何在ASP.Net Core MVC中创建级联SelectList的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在不同的应用程序中使用相同的模型值,但这次我遇到了一个问题。

I had this working in a different application with the same model values, but I've run into a problem this time around.

我想要实现的是当我在一个 SelectList 中选择一个值时,会更改另一个值中的值。目前无法使用。

What I want to achieve is that when I select one value in one SelectList, the values in a different one are changed. This is not currently working.

说我有以下型号:

public class DashboardChartsByMonthModel
{
    ...
    public SelectList TimeSliceList { get; set; }
    public TimeSlice TimeSliceVal { get; set; } // Timeslice is an Enum containing "ByMonth" and "ByQuarter"
    public SelectList StartQuarterList { get; set; }
    public string StartQuarter { get; set; }
    public SelectList StartMonthList { get; set; }
    public string StartMonth { get; set; }
    public SelectList StartYearList { get; set; }
    public string StartYear { get; set; }
    ....
    public void SetDefaults()
    {
        ...
        TimeSliceList = new SelectList(new List<SelectListItem>
        {
            new SelectListItem {Selected = true, Text = "Monthly", Value = TimeSlice.ByMonth.ToString()},
            new SelectListItem {Selected = false, Text = "Quarterly", Value = TimeSlice.ByQuarter.ToString()}
        }, "Value", "Text");
}
        StartQuarterList = new SelectList(new List<SelectListItem>
        {
            new SelectListItem {Selected = true, Text = "Q1", Value = "1"},
            new SelectListItem {Selected = false, Text = "Q2", Value = "4"},
            new SelectListItem {Selected = false, Text = "Q3", Value = "7"},
            new SelectListItem {Selected = false, Text = "Q4", Value = "10"}
        }, "Value", "Text");

        StartMonthList = new SelectList(new List<SelectListItem>
        {
            new SelectListItem {Selected = true, Text = "January", Value = "1"},
            new SelectListItem {Selected = false, Text = "February", Value = "2"},
            new SelectListItem {Selected = false, Text = "March", Value = "3"},
            new SelectListItem {Selected = false, Text = "April", Value = "4"},
            new SelectListItem {Selected = false, Text = "May", Value = "5"},
            new SelectListItem {Selected = false, Text = "June", Value = "6"},
            new SelectListItem {Selected = false, Text = "July", Value = "7"},
            new SelectListItem {Selected = false, Text = "August", Value = "8"},
            new SelectListItem {Selected = false, Text = "September", Value = "9"},
            new SelectListItem {Selected = false, Text = "October", Value = "10"},
            new SelectListItem {Selected = false, Text = "November", Value = "11"},
            new SelectListItem {Selected = false, Text = "December", Value = "12"}
        }, "Value", "Text");

        StartYearList = new SelectList(new List<SelectListItem>
        {
            new SelectListItem {Selected = false, Text = "2016", Value = "2016"},
            new SelectListItem {Selected = true, Text = "2017", Value = "2017"}
        }, "Value", "Text");

我的观点是Razor(.cshtml)页面,其中包含以下内容:

And my view, a Razor(.cshtml) page, has the following:

<body>
    ....
    <form method="post">
            <h3>By Month or Quarter</h3>
            <select id="TimeSlice" name="TimeSlice" asp-for="TimeSliceVal" asp-items="@Model.TimeSliceList"></select>
            Start:<select id="StartMonth" name="StartMonth" asp-for="StartMonth" asp-items="@Model.StartMonthList"></select>
            <select id="StartYear" name="StartYear" asp-for="StartYear" asp-items="@Model.StartYearList"></select>
    ....

有没有办法让它如果价值在第一个SelectList是Monthly,它显示MonthList的值,反之亦然,这样当第一个框改变时,第二个框也会改变?

is there a way to have it so that if the value in the first SelectList is Monthly, it displays the values of the MonthList and vice versa so that when the first box is changed, the second box changes as well?

我能够在我的其他一个应用程序中解决这个问题,但它非常麻烦,并依赖于访问相同模型属性的两个SelectLists。我想有必要有一个更好的方法来做到这一点。

I was able to solve this problem in one of my other applications but it was very cumbersome and relied on both of the SelectLists accessing the same model property. I imagine there has to be a better way to do this.

推荐答案

没有什么比这更复杂了。你所要做的就是,首先渲染第一个下拉列表,然后听取它的更改事件并读取值,并使用选定值对服务器进行ajax调用,然后返回适当的SelectListItem列表以呈现第二个下拉列表。

There is nothing complicated to do this. All you do is, first render the first dropdown and listen to the change event of that and read the value and make an ajax call with selected value to the server where it will return the appropriate list of SelectListItems to render the second dropdown.

public class DashboardChartsByMonthModel
{
   public List<SelectListItem> TimeSliceList { set;get;}
   public int SelectedTimeSlice { set;get;}

   public List<SelectListItem> TimeOptions{ set;get;}
   public int SelectedTimeOption { set;get;}    
}

在您的GET操作中,您加载第一个下拉数据

in your GET action, you load the first dropdown data

public IActionResult Create()
{
  var vm= new DashboardChartsByMonthModel();
  vm.TimeSliceList = new List<SelectListItem>
  {
        new SelectListItem {Selected = true, Text = "Monthly",
                                             Value = TimeSlice.ByMonth.ToString()},
        new SelectListItem {Selected = false, Text = "Quarterly",
                                              Value = TimeSlice.ByQuarter.ToString()}
  };
  return View(vm);
}

在您的视图中,使用SELECT标记助手

and in your view, use the SELECT tag helper

@model DashboardChartsByMonthModel
<form asp-action="Create" asp-controller="Home" method="post">    
    <select asp-for="SelectedTimeSlice" asp-items="@Model.TimeSliceList"></select>
    <select id="SelectedTimeOption" name="SelectedTimeOption" 
                                    data-url="@Url.Action("GetTimes")"></select>
    <input type="submit" />
</form>

使用jQuery处理更改事件的javascript非常简单

The javascript to handle change event is pretty simple with jQuery

$(function () {

    $("#SelectedTimeSlice").change(function() {
        var v = $(this).val();
        var url = $("#SelectedTimeOption").data("url") + '?value=' + v;
        $.getJSON(url,function(data) {
                $("#SelectedTimeOption").empty();
                $.each(data,
                    function(i, item) {
                        $("#SelectedTimeOption")
                     .append($("<option>").text(item.text).val(item.value));
                    });
            });
    });

});

这要求您有一个操作方法,它接受第一个下拉列表的选定选项值并返回所需的选项第二个。

This expects you have an action method which accepts the selected option value of first dropdown and return the options needed for second.

public IActionResult GetTimes(string value)
{
    if (value == TimeSlice.ByMonth.ToString())
    {
        var l = new List<SelectListItem>
        {
            new SelectListItem {Selected = true, Text = "January", Value = "1"},
            new SelectListItem {Selected = false, Text = "February", Value = "2"}
        };
        return Json(l);
    }
    var t2 = new List<SelectListItem>
    {
        new SelectListItem {Selected = true, Text = "Q1", Value = "1"},
        new SelectListItem {Selected = false, Text = "Q2", Value = "2"}
    };
    return Json(t2);
}

需要注意的重要事项是,在asp.net核心中返回的JSON是骆驼案。因此,对于每个选择选项,它是 text value 而不是 Text 价值

The important to thing to notice is, In asp.net core the returned JSON is camel case. So for each select option, it is text and value instead of Text and Value

这篇关于如何在ASP.Net Core MVC中创建级联SelectList的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆