Dynamic country specific templating (unpreserving)
by bombo
HTML
<script src="http://rniemeyer.github.com/KnockMeOut/Scripts/jquery.tmpl.js"></script>
<script src="http://cloud.github.com/downloads/SteveSanderson/knockout/knockout-1.2.1.debug.js"></script>
<script id="formTempPermDE" type="text/html">
<form id="form1" action="" method="POST">
<fieldset>
<legend>Permanent</legend>
<label for="permStreet">Straße: </label>
<input id="permStreet" type="text" data-bind="value: Street" /><br />
<label for="permZIP">PLZ: </label>
<input id="permZIP" type="text" data-bind="value: ZIP" /><br />
<label for="permCity">Stadt: </label>
<input id="permCity" type="text" data-bind="value: City" /><br />
<label for="permCountry">Land: </label>
<select id="permCountry"
data-bind="
options: viewModel.permCountries,
optionsText: 'Name',
optionsValue: 'Code',
value: Country
"
></select>
</fieldset>
</form>
</script>
<script id="formTempPermUS" type="text/html">
<form id="form1" action="" method="POST">
<fieldset>
<legend>Permanent</legend>
<input id="permStreet" type="text" data-bind="value: Street" />
<label for="permStreet">← Street</label><br />
<input id="permZIP" type="text" data-bind="value: ZIP" />
<label for="permZIP">← ZIP</label><br />
<input id="permCity" type="text" data-bind="value: City" />
<label for="permCity">← City</label><br />
<input id="permState" type="text" data-bind="value: State" />
<label for="permState" class="bold">← State</label><br />
<select id="permCountry"
data-bind="
options: viewModel.permCountries,
optionsText: 'Name',
optionsValue:...
CSS
fieldset {
border: 1px dotted #999;
margin: 10px;
padding: 5px;
}
.bold {
font-weight: bold;
}
JavaScript
function Address (country, street, zip, city, state, hasGreenCard) {
this.Street = ko.observable(street);
this.ZIP = ko.observable(zip);
this.City = ko.observable(city);
this.State = ko.observable(state);
this.Country = ko.observable(country);
this.HasGreenCard = ko.observable(hasGreenCard);
this.Country.subscribe(function(newValue) {
var countryOption = ko.utils.arrayFirst(viewModel.permCountries() || viewModel.futCountries, function(country) {
return country.Code === newValue;
});
if (countryOption) {
ko.utils.arrayForEach(countryOption.ExcludeFields, function(field) {
if (this[field] && ko.isWriteableObservable(this[field])) {
this[field](null);
}
}.bind(this));
}
}, this);
}
function CountryOption(name, code, excludeFields) {
this.Name = name;
this.Code = code;
this.ExcludeFields = excludeFields || [];
}
var viewModel = {
permCountries: ko.observableArray([
new CountryOption('Deutschland', 'PermDE', ['State', 'HasGreenCard']),
new CountryOption('USA', 'PermUS', ['HasGreenCard'])
]),
futCountries: ko.observableArray([
new CountryOption('Deutschland', 'FutDE', ['State', 'HasGreenCard']),
new CountryOption('USA', 'FutUS', ['State'])
]),
permanent: new Address('PermDE'),
future: new Address('FutDE')
};
viewModel.tmpl1 = ko.dependentObservable(function() {
if (this.Country()) {
return 'formTemp' + this.Country();
}
}, viewModel.permanent);
viewModel.tmpl2 = ko.dependentObservable(function() {
if (this.Country()) {
return 'formTemp' + this.Country();
}
}, viewModel.future);
$(document).ready(function() {
ko.applyBindings(viewModel);
});