Non observable form values
by origineil
HTML
<!-- Template: View/edit employees -->
<script type="text/html" id="viewing-template">
<p><b>Name</b>
<span style="float: right" ><span data-bind="text: firstName().value"></span> <span data-bind="text: lastName().value"></span></span>
</p>
<p><b>Fund name</b>
<span style="float: right"><span data-bind="text: fundName().value"></span>
</p>
</script>
<script type="text/html" id="editing-template">
First name: <br />
<input data-bind="value: firstName().modifiedValue" type="text"/> <span data-bind="text: firstName().value"></span><br />
Last name: <br />
<input data-bind="value: lastName().modifiedValue" type="text"/> <span data-bind="text: lastName().value"></span><br />
Fund name: <br />
<input data-bind="value: fundName().modifiedValue" type="text"/> <span data-bind="text: fundName().value"></span><br />
</script>
<!-- Main -->
<article class="content">
<h1>Employee details</h1>
<div class="employees" data-bind="foreach: { data: employees }">
<!-- Individual -->
<div class="employee-summary">
<h3>Employee details</h3>
<fieldset>
<!-- ko if: editable -->
<div class="employee" data-bind="template: {name: 'editing-template', data: $data }"> </div>
<!-- /ko -->
<!-- ko ifnot: editable -->
<div class="employee" data-bind="template: {name: 'viewing-template', data: $data }"> </div>
<!-- /ko -->
<br />
<div style="float: right; display: inline;">
<button data-bind='click: removeEmployee'>Delete</button>
<span data-bind="if: editable()"><button data-bind='click: cancelUpdate'>Cancel</button></span>
<button data-bind='click: editEmployee'>
<span data-bind="ifnot: editable()">Edit</span>
<span data-bind="if: editable()">Save</span>
</button>
</div>
<br />
<br class="clear" />
</fieldset>
</div>
<!-- End individual -->
<br />
<!-- End employees -->
</div>
<div style="clear: left">
<div style="float: right">
<button data-bind='click:...
CSS
body {
font-family: Arial, Helvetica, sans-serif;
}
}
.content {
width: 60em;
margin: 0 auto;
}
fieldset {
padding: 1em;
border: solid 1px #ccc;
}
.input-row h3, .employee h3, h3 {
padding: .25em .5em;
background-color: #eee;
margin: 0;
}
.input-row ul, ul.qtr li {
list-style: none;
}
.employees {
padding: 0;
list-style: none;
}
ul.qtr, ul.qtr li {
margin: 0;
padding: 0;
}
.clear {
clear: both;
}
button {
display: inline-block;
outline: none;
cursor: pointer;
text-align: center;
text-decoration: none;
font: 14px/100% Arial, Helvetica, sans-serif;
padding: .5em 1.3em .5em;
-webkit-border-radius: .5em;
-moz-border-radius: .5em;
border-radius: .5em;
border: solid 1px #999;
background: #eee;
}
button:hover {
text-decoration: none;
background: #ccc;
}
button:active {
position: relative;
/* top: 1px;*/
color: #000;
}
JavaScript
function ModifiedObservable() {
this.createObservable = function(){
var observable = ko.observable({value: "", modifiedValue: ""});
observable.revert = function(){this.modifiedValue = this.value; }.bind(observable())
observable.save = function(){ this.value = this.modifiedValue; }.bind(observable())
return observable
};
this.saveAccessor = function(){
return "save";
}
this.revertAccessor = function(){
return "revert";
}
}
function Employee() {
var self = this;
this.obsWrapper = new ModifiedObservable();
this.firstName = this.obsWrapper.createObservable();
this.lastName = this.obsWrapper.createObservable();
this.fundName = this.obsWrapper.createObservable();
//Toggle editability
this.editable = ko.observable(true);
// Employee summary of details
this.removeEmployee = function (employee) {
vm.removeEmployee(this);
};
this.cancelUpdate = function () {
this.editable(!this.editable());
this._handleProperties(this.obsWrapper.revertAccessor());
};
this.editEmployee = function (employee) {
var isSaving = this.editable();
this.editable(!this.editable());
if(isSaving)
{
this._handleProperties(this.obsWrapper.saveAccessor());
}
};
this._handleProperties = function(functionName)
{
for(var i = 0; i < this._getProperties().length; i++)
{
var propertyName = this._getProperties()[i];
var observable = this[propertyName];
observable[functionName]();
observable.valueHasMutated();
}
}
this._getProperties = function(){
return ["firstName", "lastName", "fundName"]
}
}
function EmployeesViewModel() {
var self = this;
self.employees = ko.observableArray([]);
self.removeEmployee = function (employee) {
self.employees.remove(employee);
...