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"></span> <span data-bind="text: lastName"></span></span>
  </p>
  <p><b>Fund name</b>
  <span style="float: right"><span data-bind="text: fundName"></span>
  </p>
</script>

<script type="text/html" id="editing-template">
  First name: <br />
    <input data-bind="value: $data.modifiedContext().firstName" type="text"/>  <span data-bind="text: firstName"></span><br />
  Last name: <br />
  <input data-bind="value: $data.modifiedContext().lastName" type="text"/>  <span data-bind="text: lastName"></span><br />
  Fund name: <br />
  <input data-bind="value: $data.modifiedContext().fundName" type="text"/>  <span data-bind="text: fundName"></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: addEmployee'>Add...

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 Employee() {

    var self = this;

    this.firstName = ko.observable("");
    this.lastName = ko.observable("");
    this.fundName = ko.observable("");

    //Toggle editability
    this.editable = ko.observable(true);

    this.modifiedContext = ko.observable({
        firstName: ko.observable(this.firstName()),
        lastName:ko.observable(this.lastName()),
        fundName: ko.observable(this.fundName())});
    
    // Employee summary of details
    this.removeEmployee = function (employee) {
        vm.removeEmployee(this);
    };

    this.cancelUpdate = function () {
        
        //reset modified context
        this.modifiedContext = ko.observable({
        firstName: ko.observable(this.firstName()),
        lastName:ko.observable(this.lastName()),
        fundName: ko.observable(this.fundName())});
        
        this.editable(!this.editable());
    };

    this.editEmployee = function (employee) {
        this.editable(!this.editable());
        vm.editEmployee(this, this.editable());
    };
 
}


function EmployeesViewModel() {

    var self = this;

    self.employees = ko.observableArray([]);

    self.removeEmployee = function (employee) {
        self.employees.remove(employee);
    };

    self.addEmployee = function () {
        self.employees.push(new Employee());
    };

    self.editEmployee = function (employee, isEditing) {
        
        if(!isEditing)
        {
            console.log("saving")
            var modifiedContext = employee.modifiedContext();
            employee.firstName(modifiedContext.firstName());
            employee.lastName(modifiedContext.lastName());
            employee.fundName(modifiedContext.fundName());
        }  
    };
}

var vm = new EmployeesViewModel();
ko.applyBindings(vm);