Click here to Skip to main content
15,886,840 members
Articles / Programming Languages / Javascript

Knockout that Cascading dropdown

Rate me:
Please Sign up or sign in to vote.
4.50/5 (7 votes)
9 Mar 2012CPOL1 min read 43.6K   12   4
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.

HTML
<!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:

C#
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 knock 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)


Written By
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

Comments and Discussions

 
QuestionMy vote of 5 Pin
James Van Buskirk24-Sep-14 5:21
James Van Buskirk24-Sep-14 5:21 
AnswerRe: My vote of 5 Pin
marcofranssen2-Oct-14 0:28
professionalmarcofranssen2-Oct-14 0:28 
SuggestionExcellent Article Pin
SohelElite13-Dec-12 0:05
SohelElite13-Dec-12 0:05 
QuestionHow to make it work in subsequent dropdown value combinations? Pin
André Luiz Pires2-Nov-12 13:54
André Luiz Pires2-Nov-12 13:54 

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

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