Untitled 1
Cascading DropDownLists using "Eager Loading" on client side
One of my earlier articles (Creating
Cascading DropDownLists using ASP.NET MVC 4 and jQuery) shows how to create
cascading DropDownLists by making Ajax calls to the MVC action methods. While
that approach is quite common and popular recently a reader asked whether
something similar can be done without making any Ajax calls. If you want to
implement cascading dropdownlists purely on client side then you will need to
"eagerly load" all the data needed by them at the time of loading the page. This
data can be stored in a hidden field and used as and when needed. Obviously this
technique is not suitable for huge amount of data since everything is loaded at
once on the client side. However, if the data is small and you understand the
implications of loading it in advance here is how you can accomplish the task...
As an example we will use the same Country - Cities example. The entity data
model for Countries and Cities table is shown below:

To hold the data that is to be sent to the client we create a POCO as shown
below:
public class CountryCity
{
public string Country { get; set; }
public List<string> Cities { get; set; }
}
The CountryCity class has Country property that holds a CountryName from the
database and the Cities property holds a List of CityName values. As mentioned
earlier the data will be sent to the client in the form of a hidden form field.
To store data in the hidden field we use JSON format. The code that does this
job goes inside the Index action method and is shown below:
public ActionResult Index()
{
LocationsDbEntities db = new LocationsDbEntities();
var query = from c in db.Countries
orderby c.CountryName ascending
select new {
CountryName = c.CountryName,
Cities = c.Cities.ToList() };
List<CountryCity> finalData = new List<CountryCity>();
foreach (var country in query)
{
CountryCity obj = new CountryCity();
obj.Country = country.CountryName;
obj.Cities = new List<string>();
foreach (var city in country.Cities)
{
obj.Cities.Add(city.CityName);
}
finalData.Add(obj);
}
string jsonData = JsonConvert.SerializeObject(finalData);
ViewBag.LocationData = jsonData;
return View();
}
The above code selects all the countries and their cities in an anonymous
type using LINQ to Entities query. It then iterates through the results and
forms a List of CountryCity objects. Once the whole List is formed it serializes
that data into a string using Json.NET component. The SerializeObject() method
of the JsonConvert class does that job. This string will hold the data in JSON
format. This JSON data is then passed to the view using LocationData ViewBag
property. A sample JSON data after serialization is shown below:
[
{"Country":"USA",
"Cities":["Redmond","Seattle"]},
{"Country":"UK",
"Cities":["London"]}
{"Country":"India",
"Cities":["Bangalore","Delhi"]}
]
The Index view that stores the LocationData ViewBag property into a hidden
form field is shown below:
<form action="/home/processform" method="post">
<input type="hidden"
id="locationdata"
name="locationdata"
value="@ViewBag.LocationData" />
<select id="country" name="country"></select>
<br /><br />
<select id="city" name="city"></select>
<br /><br />
<input type="submit" value="Submit" />
</form>
As you can see the JSON data is stored in locationdata hidden form field. You
will need to access this data for displaying it in the country and state
dropdownlists. The jQuery code that does that is shown below:
<script type="text/javascript">
var locationData;
$(document).ready(function () {
locationData = JSON.parse($("#locationdata").val());
for (var i = 0; i < locationData.length;i++)
{
$("#country").append("<option>" +
locationData[i].Country +
"</option>");
}
$("#country").change(function () {
var selectedCountry = $("#country").val();
for (var i = 0 ; i < locationData.length; i++)
{
if(locationData[i].Country==selectedCountry)
{
$("#city").empty();
for(var j=0;j<locationData[i].Cities.length;j++)
{
$("#city").append("<option>" +
locationData[i].Cities[j] +
"</option>");
}
return;
}
}
});
});
</script>
The above jQuery code declares a global variable - locationData - for storing
the location data. The ready() function reads the hidden form field value and
parses it into a JavaScript object using JSON.parse() method. A for loop then
iterates through the locationData array and adds entries to the country
dropdownlist using append() method.
The change() method wires the change event handler for the country
dropdownlist. The change event handler iterates through the locationData array
and finds the country matching the selection in the country dropdownlist. The
code then retrieves cities for that country and populates the city dropdownlist.
That's it! Run the Index view and test whether it works as expected.