By definition (my own) a cascading dropdown list(s) is a set of dropdown list(s) dependent on their parent dropdown list. In this blog post we’ll see how this can be achieved in ASP.NET’s MVC pattern, with the help of some client-side scripting too. For simplicity I will be using the standard template that Visual Studio creates for you when you create a new project. Also, I uploaded the source code to this GitHub location.
All right so let’s say that we’re going to have three dropdown lists, and through these we will be able to drill down from continent, to countries, to cities. All the data in this project is hard coded but it can easily be retrieved from a database or some other source. So first thing we’ll do is update the Index method in the HomeController to make it look like the following;
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public ActionResult Index() | |
{ | |
continents = new List(); | |
continents.Add(new SelectListItem { Text = "Select continent", Value = "0" }); | |
continents.Add(new SelectListItem { Text = "Europe", Value = "1" }); | |
continents.Add(new SelectListItem { Text = "North America", Value = "2" }); | |
continents.Add(new SelectListItem { Text = "South America", Value = "3" }); | |
ViewData["continents"] = continents; | |
countries = new List(); | |
countries.Add(new SelectListItem { Text = "Select country", Value = "0" }); | |
ViewData["countries"] = countries; | |
cities = new List(); | |
cities.Add(new SelectListItem { Text = "Select city", Value = "0" }); | |
ViewData["cities"] = cities; | |
return View(); | |
} |
So we created three lists of type SelectListItem and filling them with some data, and then passing them to our view using the ViewData. These lists can also be bound to a model and then pass the model to the view. I chose the ViewData option for simplicity. Within the view we need to create three dropdown lists and make a reference to the ViewData.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="row"> | |
<div class="col-md-4"> | |
@Html.DropDownList("continents", ViewData["continents"] as List) | |
</div> | |
<div class="col-md-4"> | |
@Html.DropDownList("countries", ViewData["countries"] as List) | |
</div> | |
<div class="col-md-4"> | |
@Html.DropDownList("cities", ViewData["cities"] as List) | |
</div> | |
</div> |
Now we got three dropdown lists with some data in them. For the next part we need to add some client-side scripting so we can load more data dynamically. Using Jquery we will make an AJAX call and get data according to what the user selected.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$("#continents").change(function () { | |
$("#countries").empty(); | |
$.ajax({ | |
type: 'POST', | |
url: '/Home/GetCountries', | |
dataType: 'json', | |
data: { selectedValue: $("#continents").val() }, | |
success: function (areas) { | |
$.each(areas, function (i, area) { | |
$("#countries").append('' + area.Text + ''); | |
}); | |
}, | |
error: function (ex) { | |
alert('Failed to retrieve countries.' + ex); | |
} | |
}); | |
return false; | |
}); | |
$("#countries").change(function () { | |
$("#cities").empty(); | |
$.ajax({ | |
type: 'POST', | |
url: '/Home/GetCities', | |
dataType: 'json', | |
data: { selectedValue: $("#countries").val() }, | |
success: function (cases) { | |
$.each(cases, function (i, ucase) { | |
$("#cities").append('' + ucase.Text + ''); | |
}); | |
}, | |
error: function (ex) { | |
alert('Failed to retrieve cities.' + ex); | |
} | |
}); | |
return false; | |
}); |
Back to the HomeController we are going to create two entry points and do our logic in there.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public JsonResult GetCountries(string selectedValue) | |
{ | |
countries = new List(); | |
countries.Add(new SelectListItem { Text = "Select country", Value = "0" }); | |
switch (selectedValue) | |
{ | |
case "1": | |
countries.Add(new SelectListItem { Text = "United Kingdom", Value = "1" }); | |
countries.Add(new SelectListItem { Text = "Italy", Value = "2" }); | |
countries.Add(new SelectListItem { Text = "Greece", Value = "3" }); | |
break; | |
case "2": | |
// more countries | |
break; | |
case "3": | |
// more countries | |
break; | |
} | |
return Json(new SelectList(countries, "Value", "Text")); | |
} | |
public JsonResult GetCities(string selectedValue) | |
{ | |
cities = new List(); | |
cities.Add(new SelectListItem { Text = "Select city", Value = "0" }); | |
switch (selectedValue) | |
{ | |
case "1": | |
cities.Add(new SelectListItem { Text = "Glasgow", Value = "1" }); | |
cities.Add(new SelectListItem { Text = "London", Value = "2" }); | |
cities.Add(new SelectListItem { Text = "Edinburgh", Value = "3" }); | |
break; | |
case "2": | |
// more cities | |
break; | |
case "3": | |
// more cities | |
break; | |
case "4": | |
// more cities | |
break; | |
case "5": | |
// more cities | |
break; | |
// more cases | |
} | |
return Json(new SelectList(cities, "Value", "Text")); | |
} |
And that should be it. Feel free to share your thoughts if you have any suggestions. Until the next post.
Bjorn