Knockout that cascading dropdown

Marco Franssen

Marco Franssen /

3 min read493 words

Cover Image for Knockout that cascading dropdown

In this article I will explain how you can make cascading dropdowns with Knockout.js. Knockout.js is a JavaScript library which provides you some stuff to implement the MVVM pattern.  Knockout provides you the following stuff:

  • Declarative bindings: (Easily associate DOM elements with model data using a concise, readable syntax);
  • Automatic UI Refresh: (When your data model's state changes, your UI updates automatically)
  • Dependency tracking: (Implicitly set up chains of relationships between model data, to transform and combine it)
  • Templating: (Quickly generate sophisticated, nested UIs as a function of your model data)

In the example below I use jQuery to get some json from the server.

<!DOCTYPE html>
        <title>Knockout js cascading dropdown example</title>
        <script src="jquery-1.8.2.min.js" type="text/javascript"></script>
        <script src="knockout-2.1.0.js" type="text/javascript"></script>
        var viewModel = {
            country: ko.observable(),
            countries: ko.observableArray(),
            state: ko.observable(),
            states: ko.observableArray(),
            city: ko.observable(),
            cities: ko.observableArray(),
            result: ko.observable()
        viewModel.countrySelect = ko.computed({
            write: function (country) {
                $.getJSON('http://localhost:56502/KnockoutJS/CascadingDropdown/States/' + country.value, null, function (response) {
            owner: viewModel
        viewModel.stateSelect = ko.computed({
            read: viewModel.state,
            write: function (state) {
                $.getJSON('http://localhost:56502/KnockoutJS/CascadingDropdown/Cities/' + state.value, null, function (response) {
            owner: viewModel
        viewModel.result = ko.computed(function () {
            var result = '';
            result += != undefined ? 'Country: ' + + ', ' : '';
            result += this.state() != undefined ? 'State: ' + this.state().text + ', ' : '';
            result += != undefined ? 'City: ' + : '';
            return result;
        }, viewModel);
        $(function () {
            $.getJSON('http://localhost:56502/KnockoutJS/CascadingDropdown/Countries/', null, function (response) {
        <h1>Knockout js cascading dropdown example</h1>
        <select data-bind="options: countries, optionsCaption: 'Choose country...', optionsValue: function(item) { return item.value; }, optionsText: function(item) { return item.text; }, value: countrySelect, valueUpdate: 'change'" id="Country" name="Country"></select>
        <select data-bind="options: states, optionsCaption: 'Choose state...', optionsValue: function(item) { return item.value; }, optionsText: function(item) { return item.text; }, value: stateSelect, valueUpdate: 'change'" id="State" name="State"></select>
        <select data-bind="options: cities, optionsCaption: 'Choose city...', optionsValue: function(item) { return item.value; }, optionsText: function(item) { return item.text; }, value: city, valueUpdate: 'change'" id="State" name="City"></select>
        <span data-bind="text: result"></span>

The json data should be an array of objects containing a value and text property. As you can see I use the html5 data-bind attribute to map my view model to my UI elements.

For example your ASP.NET MVC3 action could look like this.

public JsonResult States(string country)
    var states = _countryRepository.GetStates(country)
        .Select(s => new {
            text = s.StateName,
            value = c.StateCode
    return new JsonResult { Data = states, JsonRequestBehavior = JsonRequestBehavior.AllowGet };

I wrote the examples in notepad, so there could be some issues. However if I did my job well this should be all to let all the magic happen.

Didn't this knocked out a bunch of javascript code you would write normally?

If you like it share it! If you don't share it!

You have disabled cookies. To leave me a comment please allow cookies at functionality level.

More Stories

Cover Image for jQuery events contributes to clean Javascript

jQuery events contributes to clean Javascript

Marco Franssen

Marco Franssen /

As the title reveals, this blogpost is about some clean javascript code example. Many developers dislike javascript because of different reasons. I think javascript is a pretty cool language. To prevent developers from disliking it and encourage them to show how great javascript can be, we all as developers have to write javascript in a clean way. This way lesser developers will be discouraged to use it. In this blogpost I will show you how to write some OOP style javascript, which you know as…

Cover Image for Install Win 8 developer preview in your VirtualBox

Install Win 8 developer preview in your VirtualBox

Marco Franssen

Marco Franssen /

Since today you can download the pre-release of Windows 8 (Developer preview). Since testing this new stuff out can be risky, it is best you do it in a virtual machine. You can download it the developer preview from the new Windows Dev Center. MSDN subscribers can download some additional win8 stuff. Before you start you have to make sure your pc supports hardware virtualization. Here you can find how to enable it in the BIOS if your system supports it.…

Cover Image for Pitfall in FakeItEasy

Pitfall in FakeItEasy

Marco Franssen

Marco Franssen /

The current project I'm doing is a CQRS based project, using the ncqrs framework. Today I came to a phase I needed some mocking done for some of my domain services. I choose FakeItEasy to handle this for me. So I started by just adding a reference to my DomainScenario project using a Nuget package. For some of my complexer scenario's I ran into some issues which took me about about 45 minutes to fix one of my tests. For fixing all other failing tests I had to do the same trick. Before I explai…

Cover Image for Lessons learned when applying DDD CQRS

Lessons learned when applying DDD CQRS

Marco Franssen

Marco Franssen /

While I was trying to apply DDD in combination with CQRS I learned myself some good lessons. I was trying to apply this in an agile approach, using the project method SCRUM. I started the project by translating all use-cases to smaller user stories. Based on this user stories I defined a first sprint. In the first sprint I didn't had or make a design for the complete domain. So I wasn't completely sure if I made the right decision for the 'aggregate root / bounded contexts' needed for the firs…