Sync Between Year and Month for Dropdownlist

2019-09-19 19:22发布

问题:

Goal:
Sync with two dropdownlist that is for year and month in asp.net mvc 4.

Problem:
These two dropdownlist are separated and I wonder how to sync them?

Info:
*Today, year and month are located inside of Viewbag.
*It is important that the list must be inside of ViewBag, if possible.
*Please remember that if you change the year, the dropdownlist for month also will be changing.
*The list of the year starts with the highest value. THe bottom of the list begins with the oldest year.

This the table with available year and month:

--------------
Year    Month
--------------
2000    10
2000    12
2001    1
2001    2
2001    3
2001    4

etc...

string selectedmonth = 1; 
string selectedyear = 2000;



monthlist.Add(new SelectListItem { Selected = "2000" == selectedyear ? true : false, Text = "2000", Value = "2000" });
monthlist.Add(new SelectListItem { Selected = "2001" == selectedyear ? true : false, Text = "2001", Value = "2001" });



monthlist.Add(new SelectListItem { Selected = "1" == selectedmonth ? true : false, Text = "January", Value = "1" });
monthlist.Add(new SelectListItem { Selected = "2" == selectedmonth ? true : false, Text = "February", Value = "2" });
monthlist.Add(new SelectListItem { Selected = "3" == selectedmonth ? true : false, Text = "March", Value = "3" });
monthlist.Add(new SelectListItem { Selected = "4" == selectedmonth ? true : false, Text = "April", Value = "4" });
monthlist.Add(new SelectListItem { Selected = "5" == selectedmonth ? true : false, Text = "May", Value = "5" });
monthlist.Add(new SelectListItem { Selected = "6" == selectedmonth ? true : false, Text = "June", Value = "6" });
monthlist.Add(new SelectListItem { Selected = "7" == selectedmonth ? true : false, Text = "July", Value = "7" });
monthlist.Add(new SelectListItem { Selected = "8" == selectedmonth ? true : false, Text = "August", Value = "8" });
monthlist.Add(new SelectListItem { Selected = "9" == selectedmonth ? true : false, Text = "September", Value = "9" });
monthlist.Add(new SelectListItem { Selected = "10" == selectedmonth ? true : false, Text = "October", Value = "10" });
monthlist.Add(new SelectListItem { Selected = "11" == selectedmonth ? true : false, Text = "November", Value = "11" });
monthlist.Add(new SelectListItem { Selected = "12" == selectedmonth ? true : false, Text = "December", Value = "12" });

ViewBag.YearList = yearlist;
ViewBag.MonthList = monthlist;

回答1:

You need to use javascript/jquery to handle the .change() event of the SelectedYear dropdown and update the SelectedMonth listbox, for example by calling a server method using ajax. You will find all this easier if you use a view model and strongly bind to your properties rather than using ViewBag for everything. Note that since you can have multiple months for a year, your SelectedMonths property needs to be an array.

public class SampleViewModel
{
    public int SelectedYear { get; set; }
    public IEnumerable<int> SelectedMonths { get; set; }
    public IEnumerable<SelectListItem> Years { get; set; }
    public IEnumerable<SelectListItem> Months { get; set; }
}

and in the GET method, initialize and return an instance of the view model

[HttpGet]
public ActionResult Edit()
{
    SampleViewModel model = new SampleViewModel()
    {
        SelectedYear = 2001, // set default
        SelectedMonths = new List<int>{ 1, 2 }, // set default based on default year
        Years = new List<SelectListItem>
        {
            new SelectListItem(){ Value = "2000", Text = "2000" },
            new SelectListItem(){ Value = "2001", Text = "2001" }
        },
        Months = new List<SelectListItem>
        {
            new SelectListItem(){ Value = "1", Text = "January" },
            new SelectListItem(){ Value = "2", Text = "February" },
            ....
        }
    };
    return View(model);
}

and in the view

@model SampleViewModel
....
@using (Html.BeginForm())
{
    ....
    @Html.DropDownListFor(m => m.SelectedYear, Model.Years) 
    ....
    @Html.ListBoxFor(m => m.SelectedMonths, Model.Months)
    ....
}

Then add a script to handle the change event of the dropdownlist

<script type="text/javascript">
    var url = '@Url.Action("FetchMonths")';
    $('#SelectedYear').change(function() {
        $.getJSON(url, { selectedYear: $(this).val() }, function(data) {
            $('#SelectedMonths').val(data);
        });
    });
</script>

which would call the following method

public JsonResult FetchMonths(int selectedYear)
{
    IEnumerable<int> months = db.yourTable().Where(x => x.Year == selectedYear).Select(x => x.Month);
    return Json(months, JsonRequestBehavior.AllowGet);
}