PixelPaul PixelPaul - 4 months ago 21
jQuery Question

asp.net MVC cascading dropdown lists

I'm trying to create some cascading dropdown lists in asp.net. The lists are populating correctly on page load:

<div class="form-group">
@Html.LabelFor(m => m.Country)
@Html.DropDownListFor(m => m.Country, new SelectList(Model.CountriesDDL, "CountryCode", "Country"), "--Select--", new { @class = "form-control" })
</div>
<div class="form-group">
@Html.LabelFor(m => m.Region)
@Html.DropDownListFor(m => m.Region, new SelectList(Model.RegionsDDL, "CountryCode", "RegionName"), "--Select--", new { @class = "form-control" })
</div>


I'm using jQuery/Ajax in the view:

<script type="text/javascript">
$(document).ready(function () {
$("#Country").change(function () {
$("#Region").empty();
$.ajax({
type: 'POST',
url: '@Url.Action("GetRegionsByCountryCode")',
dataType: 'json',
data: { countryCode: $("#Country").val() },
success: function (data) {
$.each(data, function (index, value) {
$("#Regions").append('<option value="'
+ value.CountryCode + '">'
+ value.RegionName + '</option>');
});
},
error: function (ex) {
alert('Failed to retrieve regions.' + ex);
}
});
return false;
})
});
</script>


That is calling a controller method:

[HttpPost]
public JsonResult GetRegionsByCountryCode(string countryCode)
{
var regions = _uiRepository.GetRegionsByCountryCode(countryCode);
return Json(regions);
}


But when I change a select from the "Country" dropdown, I get a popup dialog that says:

Failed to retrieve regions.[object Object]


I'm not sure what that error means or how I can debug this. I set a break point on the controller method, but it never hits it?

Answer

Your drop down id is Region but in your success function you are using Regions

Make this one small change and it will work.

Controller:

public class MyCountry
{
    public int CountryCode { get; set; }
    public string Country { get; set; }
}

public class Region
{
    public int CountryCode { get; set; }
    public string RegionName { get; set; }
}

public class ViewModel
{
    public List<MyCountry> Country { get; set; }
    public List<Region> Region { get; set; }
}

public class DropDownExampleController : Controller
{
    public ActionResult Index()
    {
        var model = new ViewModel();

        var c1 = new MyCountry { Country = "South Africa", CountryCode = 1 };
        var c2 = new MyCountry { Country = "Russia", CountryCode = 2 };

        model.Country = new List<MyCountry> { c1, c2 };

        var r1 = new Region { RegionName = "Gauteng", CountryCode = 1};
        var r2 = new Region { RegionName = "Western Cape", CountryCode = 1 };
        var r3 = new Region { RegionName = "Siberia", CountryCode = 2 };

        model.Region = new List<Region> { r1, r2,r3};
        return View(model);
    }

    [HttpPost]
    public JsonResult GetRegionsByCountryCode(string countryCode)
    {
        var r1 = new Region { RegionName = "Gauteng", CountryCode = 1 };
        var r2 = new Region { RegionName = "Western Cape", CountryCode = 1 };
        var r3 = new Region { RegionName = "Siberia", CountryCode = 2 };

        var regions = new List<Region> { r1, r2, r3 };

        var results = regions.Where(r => r.CountryCode == Int32.Parse(countryCode)).ToList();

        return Json(results);
    }
}

View:

@model MVCTutorial.Controllers.ViewModel

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.3/jquery.min.js"></script>
<script type="text/javascript">
    $(function () {
        $("#Country").change(function () {

            var countryCode = $("#Country").val();
            $("#Region").empty();

            $.ajax({
                type: 'POST',
                url: '@Url.Action("GetRegionsByCountryCode")',
                data: { countryCode: countryCode },
                success: function (data) {
                    $.each(data, function (index, value) {
                        $("#Region").append('<option value="'
                                             + value.CountryCode + '">'
                                             + value.RegionName + '</option>');
                    });
                },
                error: function (ex) {
                    alert('Failed to retrieve regions.' + ex);
                }
            });
            return false;
        })
    });
</script>

<div class="form-group">
    Country
    @Html.DropDownListFor(m => m.Country, new SelectList(Model.Country, "CountryCode", "Country"), "--Select--", new { @class = "form-control" })
</div>
<div class="form-group">
    Region
    @Html.DropDownListFor(m => m.Region, new SelectList(Model.Region, "CountryCode", "RegionName"), "--Select--", new { @class = "form-control" })
</div>