A Small Form and Cascading Drop Down with KnockoutJS
by Avi Algaly
HTML
<script src="http://cloud.github.com/downloads/SteveSanderson/knockout/knockout-2.2.0.debug.js"></script>
<fieldset>
<label for="resident-name">Resident Name</label>
<input type="text" id="resident-name" data-bind="value: residentName, valueUpdate: 'afterkeydown'" />
<label for="street-name">Street</label>
<input type="text" id="street-name" data-bind="value: streetName, valueUpdate: 'afterkeydown'" />
<label for="number-name">Number</label>
<input type="text" id="number-name" data-bind="value: numberName, valueUpdate: 'afterkeydown'" />
<label for="country-name">CountryName</label>
<select id="country-name" data-bind="options: availableCountries, optionsText: 'name', optionsCaption: 'Choose Country...', value: countryName"></select>
<label for="city-name">City Name</label>
<select id="city-name" data-bind="options: availableCities, optionsText: 'name', optionsCaption: 'Choose City...', value: cityName"></select>
<button id="submit-command" data-bind="click: submitClick, enable: validateModel">Submit</button>
</fieldset>
<button id="show-info-command" >Show Info</button>
SCSS
fieldset {
border: 1px dotted #bbb;
padding: 5px;
label {
display: block;
float: left;
width: 100px;
line-height: 22px;
clear: left;
}
input, select {
margin-bottom: 5px;
width: 130px;
display:block;
}
}
JavaScript
var newPropertyViewModel = {
residentName: ko.observable("John Doe"),
streetName: ko.observable("Sesame"),
numberName: ko.observable("5"),
cityName: ko.observable(""),
countryName: ko.observable(""),
availableCountries: ko.observableArray([]),
submitClick: function() {
alert("Submitting data...");
}
};
newPropertyViewModel.availableCities = ko.dependentObservable(function() {
var country = this.countryName();
var availableCities = {
cities: []
};
if (country) {
availableCities = ko.utils.arrayFilter(cities, function(currentCity) {
return currentCity.countryId === country.id;
});
}
if (availableCities.length && availableCities.length > 0) {
availableCities = availableCities[0];
}
return availableCities.cities;
}, newPropertyViewModel);
newPropertyViewModel.validateModel = ko.computed(function() {
var isValid = (this.residentName() || false) && (this.streetName() || false) && (this.numberName() || false) && (this.cityName() || false) && (this.countryName() || false);
return isValid;
}, newPropertyViewModel);
ko.applyBindings(newPropertyViewModel);
$("#show-info-command").on("click", function() {
var currentState = {
residentName: newPropertyViewModel.residentName(),
streetName: newPropertyViewModel.streetName(),
numberName: newPropertyViewModel.numberName(),
cityName: newPropertyViewModel.cityName(),
countryName: newPropertyViewModel.countryName()
};
alert(JSON.stringify(currentState));
});
// load countries
var countries = [
{
id: 1,
name: "Israel"},
{
id: 2,
name: "USA"},
{
id: 3,
name: "Canada"}
];
// load cities
var cities = [
{
countryId: 1,
cities: [
{
id: 11,
name: "Tel Aviv"},
{
id: 12,
name: "Jerusalem"},
{
id: 13,
name: "Haifa"},
{
id: 14,
name:...