@Blog.Author(Nandip Makwana) .LearningExperience(ASP.NET, ASP.NET MVC, IIS, jQuery & Technology Surrounding it...)

June 24, 2012 comment , , , ,

Cascading drop down with knockout.js & ASP.NET MVC

In this basic post, we will see how to build cascading drop down with the help of knockoutjs and ASP.NET MVC. However building cascading drop down with ASP.NET MVC is not a big deal and if we google it out, we will find plenty of solutions and post which demonstrate this. But here idea is to show how we can leverage knockoutjs to create UI which update itself (obviously based on some user interaction) without writing JavaScript which build UI or DOM element each and every time. Later on we can use same technique to build application where UI keep refreshing frequently. Sample can be downloaded from here.

In this post, initially user is presented with drop down which display country and upon selecting country user is presented with another drop down which list down state for the selected country. In this sample we will use jQuery.getJSON to fetch list of states for selected country. Server will return state list in JSON format i.e. JavaScript array.

Magic of knockoutjs

As mentioned earlier we can build cascading drop down with ASP.NET MVC even without using knockoutjs but in that case we have to iterate through state list and we need to create state drop down by string manipulation in JavaScript. Here in case of cascading drop down, data source (state list) refresh based on only one factor (when selected country changes) but consider scenario where data source keep changing frequently and that too based on more than one factor. In such scenario we need to take care of each and every case while building UI or DOM element with string manipulation. Now this is the situation where knockoutjs comes in picture! Yes instead creating UI or DOM element with string manipulation, we can create view (UI) and model (data source) with MVVM pattern used by knockoutjs and then after whenever data source refresh at that time we only need to update underlying viewmodel and rest will be taken care by knockoutjs including updating UI based on refreshed data.

Here is the code for Home controller & State model class.

public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Country = new SelectList(Country.GetCountryList(), "Code", "Name");
        return View();
    }
 
    public ActionResult GetStates(string id = "")
    {
        var stateList = State.GetStates()
            .Where(s => s.CountryCode.ToLower() == id.ToLower());
        return this.Json(stateList, JsonRequestBehavior.AllowGet);
    }
}
 
// State model class
// Property of State class is used to 
// bind view with knockoutjs viewmodel
public class State
{
    public string CountryCode { get; set; }
    public int StateId { get; set; }
    public string StateName { get; set; }
}

This is how index.cshtml looks like.

<p>
<b>Select Country :</b> @Html.DropDownList("ddlCountry", ViewBag.Country as SelectList, "Select...", new { onchange = "FetchStates();" })
</p>
 
<p data-bind="visible: states().length > 0">
<b>Select State :</b> <select data-bind="options: states, optionsText: 'StateName', optionsValue: 'StateId', optionsCaption: 'Choose...'"></select>
</p>

And this is how our viewmodel is defined in JavaScript.

function CascadingDDLViewModel() {
    this.states = ko.observableArray([]);
}
 
var objVM = new CascadingDDLViewModel();
ko.applyBindings(objVM);

We can see in above code that we are creating view model with states property of type ko.observableArray. Observable type in knockoutjs notify automatically whenever underlying object is updated. In index.cshtml snippet, we are using this states property with data-bind attribute. With the help of data-bind attribute, we are binding DOM element behavior (whether to show or hide, updating select drop down options etc.) with knockoutjs viewmodel. So whenever underlying viewmodel updates, at that time DOM elements are also updated automatically.

Following JavaScript function will be called whenever user change selected country. We are using jQuery.getJSON to fetch states list and we are updating underlying viewmodel with server response. That’s it; refreshing state drop down will be taken care by knockoutjs we do not need to iterate through state list and do not require to rebuild drop down by JavaScript string operation.

function FetchStates() {
    var countryCode = $("#ddlCountry").val();
    $.getJSON("/Home/GetStates/" + countryCode, null, function (data) {
        objVM.states(data);
    });
}

So this was basic post to demonstrate how we can use knockoutjs with ASP.NET MVC to create application where UI keep refreshing frequently without bothering about rebuilding UI with JavaScript string operation. Sample code for this post can be downloaded from here.

comments powered by Disqus

Featured Content

Resources & Tools

About Nandip Makwana

Nandip Makwana is passionate about digital world and web. He completed his Masters in Computer Application in June 2011. Currently he is working as a Software Engineer. He has shown great promise and command over ASP.NET and technologies surrounding it during his academic years and professorial life...continue reading