Click here to Skip to main content
Click here to Skip to main content

Knockout that cascading dropdown

, 9 Mar 2012
Rate this:
Please Sign up or sign in to vote.
How you can make cascading dropdowns with Knockout. Knockout is a JavaScript library which provides you some stuff to implement the MVVM pattern.

In this article I will explain how you can make cascading dropdowns with Knockout. Knockout 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 server data.

<!DOCTYPE html>
<html>
    <head>
        <title>Knockout js cascading dropdown example</title>
        <script src="jquery-1.6.3.min.js" type="text/javascript"></script>
        <script src="knockout-1.2.1.js" type="text/javascript"></script>
        <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.dependentObservable({
            read: viewModel.country,
            write: function (country) {
                this.country(country);
                $.getJSON('http://localhost:56502/KnockoutJS/CascadingDropdown/States/' + 
                          country.value, null, function (response) {
                    viewModel.states(response);
                });
            },
            owner: viewModel
        });
        viewModel.stateSelect = ko.dependentObservable({
            read: viewModel.state,
            write: function (state) {
                this.state(state);
                $.getJSON('http://localhost:56502/KnockoutJS/CascadingDropdown/Cities/' + 
                          state.value, null, function (response) {
                    viewModel.cities(response);
                });
            },
            owner: viewModel
        });
        viewModel.result = ko.dependentObservable(function () {
            var result = '';
            result += this.country() != undefined ? 'Country: ' + this.country().text + ', ' : '';
            result += this.state() != undefined ? 'State: ' + this.state().text + ', ' : '';
            result += this.city() != undefined ? 'City: ' + this.city().text : '';
            return result;
        }, viewModel);

        $(function () {
            $.getJSON('http://localhost:56502/KnockoutJS/CascadingDropdown/Countries/', 
                      null, function (response) {
                viewModel.countries(response);
            });
            ko.applyBindings(viewModel);
        });
        </script>
    <head>
    <body>
        <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>
    </body>
</html>

The JSON server 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 Json(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!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

marcofranssen
Software Developer Atos
Netherlands Netherlands
I am a .NET Software Developer at Atos International. Architecture, CQRS, DDD, C#, ASP.NET, MVC3, HTML5, Jquery, WP7, WPF, ncqrs, Node.js
Follow on   Twitter   Google+   LinkedIn

Comments and Discussions

 
SuggestionExcellent Article PinmemberSohelElite13-Dec-12 0:05 
QuestionHow to make it work in subsequent dropdown value combinations? PinmemberAndré Luiz Pires2-Nov-12 13:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140814.1 | Last Updated 9 Mar 2012
Article Copyright 2012 by marcofranssen
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid