MVC 3 is becoming hugely popular thanks to Razor and the Helpers that make building web applications much easier. One of the common requirements in web development, both with web forms as well as MVC based development, is the cascading dropdownlist. Now, for Web Forms, we can use a variety of options viz. server side programming, jQuery or using the AJAX Control Toolkit’s cascading dropdownlist control for accomplishing this.

I saw a few samples on the internet that used the erstwhile Microsoft AJAX Library along with MVC and also few more samples which used hard coded values for wiring up the cascading dropdown. I have built this sample using Database with 3 tables i.e. Cars, Makes & Colours. The colours table is actually redundant but for the sake of showing a 3 dropdown hierarchy I have made it a relational table – just for the purpose of the sample. Also, all the cars mentioned are the brands that I could recollect and driven around in India Smile

To begin with, lets examine the Database – CascadeSample. It has 3 tables

i. Cars

ii. Models

iii. Colours

I filled in some sample data. At the end of this post, I would provide link for downloading the database scripts as well as the solution.

First, lets create our MVC 3 Application using “File – New Project – ASP.NET MVC 3 Web Application” give it a name “CascadingDropdownSample” and select the “Internet Application” and click ok. This would create the basic scaffolding structure with Membership API. We won’t need it though.

As always with MVC, lets build the Model by right click Models Folder – Add – New Item and search for ADO.NET Entity in the search box of the Dialog.

Chose the ADO.NET Entity Data Model Template and give it a name CarModel.edmx and click Add.

Choose the “Generate from Database” option and in the Next steps, connect to the CascadeSample database and select all the 3 tables and then finish the steps to generate the Entity Model. Our Entity Model is now ready.

Next step is to start wiring up the Controller Actions. For the purpose of this simple demo, lets just use the default HomeController.

Lets add using CascadingDropdownSample.Models; to the namespaces in the HomeController.

Lets add CascadeSampleEntities cse = new CascadeSampleEntities(); within the class

Lets add the following within the Index Action.

public ActionResult Index()
{

ViewBag.Cars = cse.Cars.ToList();
ViewBag.Models = cse.Models.ToList();
ViewBag.Colours = cse.Colours.ToList();
return View();
}

 

Lets switch to the View (ROOT – Views – Home – Index.cshtml) and edit it to look as follows:-

@model CascadingDropdownSample.Models.CascadeSampleEntities
@{
ViewBag.Title = "Home Page";
}

<h2>Cars</h2>
<p>
@Html.DropDownListFor(Model => Model.CarId, new SelectList(ViewBag.Cars as System.Collections.IEnumerable, "CarId", "CarName"),
"Select a Car", new { id = "ddlCars" })
</p>

When we run the page, we will get to see the List of cars in the dropdown.

For the next set of actions i.e. populating the Model and Colour, we need the following Methods.

private IList<Model> GetModels(int id)
{
return cse.Models.Where(m => m.CarId == id).ToList();
}

private IList<Colour> GetColours(int id)
{
return cse.Colours.Where(c => c.ColourId == id).ToList();
}

The next main thing we need is Action methods which can send a JSon Result for both Models and Colours.

To first get the Models by car, we add the following to the HomeController

[AcceptVerbs(HttpVerbs.Get)]
public JsonResult LoadModelsByCar(string id)
{
var modelList = this.GetModels(Convert.ToInt32(id));

var modelData = modelList.Select(m => new SelectListItem()
{
Text = m.ModelName,
Value = m.ModelId.ToString(),

});

return Json(modelData, JsonRequestBehavior.AllowGet);
}

 

and to get the Colours for the various Models, we add


[AcceptVerbs(HttpVerbs.Get)]
public JsonResult LoadColoursByModel(string id)
{
var colourList = this.GetColours(Convert.ToInt32(id));

var colourData = colourList.Select(c => new SelectListItem()
{
Text = c.ColourName,
Value = c.ColourId.ToString(),

});

return Json(colourData, JsonRequestBehavior.AllowGet);
}

 

Finally, we need to add the following jQuery handlers for the dropdownlist selection changed

<script type="text/javascript">
$(document).ready(function () {
$("#ddlCars").change(function () {
var idModel = $(this).val();
$.getJSON("/Home/LoadModelsByCar", { id: idModel },
function (carData) {
var select = $("#ddlModels");
select.empty();
select.append($('<option/>', {
value: 0,
text: "Select a Model"
}));
$.each(carData, function (index, itemData) {

select.append($('<option/>', {
value: itemData.Value,
text: itemData.Text
}));
});
});
});
$("#ddlModels").change(function () {
var idColour = $(this).val();
$.getJSON("/Home/LoadColoursByModel", { id: idColour },
function (modelData) {
var select = $("#ddlColours");
select.empty();
select.append($('<option/>', {
value: 0,
text: "Select a Colour"
}));
$.each(modelData, function (index, itemData) {

select.append($('<option/>', {
value: itemData.Value,
text: itemData.Text
}));
});
});
});
});

</script>

And then add the dropdowns for Model and Colour

<p>
@Html.DropDownListFor(Model => Model.Models, new SelectList(Enumerable.Empty<SelectListItem>(), "ModelId", "ModelName"),
"Select a Model", new { id = "ddlModels" })

</p>
<p>
@Html.DropDownListFor(Model => Model.Colours, new SelectList(Enumerable.Empty<SelectListItem>(), "ColourId", "ColourName"),
"Select a Colour", new { id = "ddlColours" })

</p>

And then, when we build and run we can get to choose the Car, Model and Make, a cascading dropdown built using jQuery and MVC 3

I have uploaded the Visual Studio 2010 Solution as well as the Scripts for the CascadeSample Database to https://skydrive.live.com/?cid=069f94a102eff49a&sc=documents&client=wnf&id=69F94A102EFF49A%21760#cid=069F94A102EFF49A&id=69F94A102EFF49A%21761&sc=documents

Feel free to download and use it for your projects Smile

Also, do share if you find better ways to implement the same.

Cheers!!