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 server data.

index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<!DOCTYPE html>
<html>
<head>
<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>
<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({
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.computed({
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.computed(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.

1
2
3
4
5
6
7
8
9
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!

Share