DK Development

The random output of a Windows developer.

DK Development

The random output of a Windows developer.




MVC2 Cascading Dropdown Lists with JSON

Today I’m going to show you how to go about creating cascading dropdown lists using JSON in MVC2. Hold onto your hats, its time to begin!

Learning ASP.NET MVC2 I thought I'd start with a relatively simple web application, this application is for keeping track of service usage across the company's physical sites (ie. Electricity, Gas, Waste, etc.).

Now first things first, I setup the Database and LinqToSql classes for my app. The table structure is MeterTypes > MeterCollections > MeterUsages. Where a MeterType is the top level (ie. Electricity, Gas, Waste, etc.) the MeterCollections are the next level down (a MeterType may contain many of these, for Electricity I have Peak and Off-Peak) and MeterUsage is the actual usage on a meter for that MeterCollection.

OK, lets get coding… We will be looking at the Create Page for the MeterUsage object, I started with the create template MVC2 gave me for this object (half of the fields are just textboxes anyway)

public ActionResult Create()
{
    var meterTypesRepo = new Models.Repo<Models.MeterType>();
    var meterTypes = from mt in meterTypesRepo.Many()
                     select new SelectListItem
                     {
                         Value = mt.MeterTypeID.ToString(),
                         Text = mt.Name
                     };
    ViewData["meterTypes"] = meterTypes;

    return View("Create");
}

Inside the Controller is where the request is handled, Now we need the data for the first list so we may as well get this here. This simply gets all the MeterTypes in the Database and converts them to SelectListItems (this is to make it easier on the page)

<div class="editor-label">
    <label for="meterTypes">Meter Type</label>
</div>
<div class="editor-field">
    <%= Html.DropDownList("meterTypes", "-- Select --")%>
</div>
<div class="editor-label">
    <label for="MeterCollectionID">Meter Collection</label>
</div>
<div class="editor-field">
    <%= Html.DropDownListFor(model => model.MeterCollectionID, new SelectList(new List<UsageInputs.Models.MeterCollection>()))%>
    <%= Html.ValidationMessageFor(model => model.MeterCollectionID) %>
</div>

Markup, Basic use of the Html.DropDownList() function for MeterTypes (this is where using SelectListItems comes in handy. Also added a default option “—Select –”. Then the MeterCollection Dropdown is a little different as this one actually maps to a property on my MeterUsage object so I used the Html.DropDownListFor() function and gave it an empty list so it would create the dropdown list but not have any items (they will be populated with Ajax.

Next is the Javascript, this simply calls my MeterCollections/GetList function with the ID of the MeterType from the selected item in the DropDown list.

$("#meterTypes").change(function () {
    $.ajaxSetup({ cache: false });
    var selectedItem = $(this).val();
    if (selectedItem == "" || selectedItem == 0) {
        //Do nothing or hide...?
    } else {
        $.getJSON('<%= ResolveUrl("~/MeterCollections/GetList/")%>' + $("#meterTypes > option:selected").attr("value"), function (data) {
            meterCollections = data;
            var items = "";             $.each(data, function (i, meterCollection) {
                items += "<option value='" + meterCollection.Value + "'>" + meterCollection.Text + "</option>";
            });
            $("#MeterCollectionID").html(items);
        });
    }
});

It also builds up the html for inside the dropdown list using a JQuery for each loop.

Now the last part is our GetList function to return JSON, so back to the controllers.

[HttpGet]
public ActionResult GetList(int id)
{
    var meterCollsRepo = new Models.Repo<Models.MeterCollection>();
    var meterCollections = from mc in meterCollsRepo.Many()
                           where mc.MeterTypeID == id
                           select new SelectListItem
                           {
                               Text = string.Format("{0} ({1})", mc.Name, mc.Mesurement),
                               Value = mc.MeterCollectionID.ToString()
                           };

    return Json(meterCollections, JsonRequestBehavior.AllowGet);
}

This function then gets all the MeterCollections that have that MeterTypeID. Here I also use the SelectListItem object as its much easier to work with in the Javascript and less work for the Serializer.

And just like that you have a Cascading DropDown List in MVC2 using Ajax.

blog comments powered by Disqus