title: How to implement cancel functionality using knockout.js
body: <p>I am working on a asp.net MVC project. and  i am using knockout.js on my view page.
  I am trying to develop a data entry grid. Everything works fine except <strong>Cancel</strong> button.</p>
  
  <p>If i change something on my UI ( view) and clicked on cancel , It is not showing me old values .it only show me the latest values.  </p>
  
  <p>Steps:</p>
  
  <ul>
  <li>When i click on edit button  it display update and cancel button.</li>
  <li>Let us say i have edited data and click on cancel , it should not reflect on my UI.</li>
  </ul>
  
  <p>Right now , even if you edit and click on <strong>cancel</strong> button , it is able to revert to old state.</p>
  
  <p>I am not going back to old state when i clickd on cancel button.
  Please suggest me some examples .</p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;html&gt;
  &lt;head&gt;
      &lt;meta name="viewport" content="width=device-width" /&gt;
      &lt;title&gt;Type Lookup....&lt;/title&gt;
      &lt;script src="~/Scripts/jquery-2.1.0.js"&gt;&lt;/script&gt;
      &lt;script src="~/Scripts/knockout-3.0.0.js"&gt;&lt;/script&gt;
  
      &lt;link href="~/Content/Site.css" rel="stylesheet" /&gt;
      &lt;link href="~/Content/bootstrap.css" rel="stylesheet" /&gt;
      &lt;script type="text/javascript"&gt;
          viewModel = {
              lookupCollection: ko.observableArray()
          };
  
          //wrapper to an observable that requires accept/cancel
          ko.protectedObservable = function (initialValue) {
              //private variables
              var _actualValue = ko.observable(initialValue),
                  _tempValue = initialValue;
  
              //computed observable that we will return
              var result = ko.computed({
                  //always return the actual value
                  read: function () {
                      return _actualValue();
                  },
                  //stored in a temporary spot until commit
                  write: function (newValue) {
                      _tempValue = newValue;
                  }
              });
  
              //if different, commit temp value
              result.commit = function () {
                  if (_tempValue !== _actualValue()) {
                      _actualValue(_tempValue);
                  }
              };
  
              //force subscribers to take original
              result.reset = function () {
                  _actualValue.valueHasMutated();
                  _tempValue = _actualValue();   //reset temp value
              };
  
              return result;
          };
  
          $(document).ready(function () {
              $.ajax({
                  type: "GET",
                  url: "/Home/GetIndex",
              }).done(function (data) {
                  $(data).each(function (index, element) {
                      var mappedItem =
                          {
                              Id: ko.observable(element.Id),
                              Key: ko.observable(element.Key),
                              Value: ko.observable(element.Value),
                              Mode: ko.observable("display")
                          };
                      viewModel.lookupCollection.push(mappedItem);
                  });
                  ko.applyBindings(viewModel);
              }).error(function (ex) {
                  alert("Error.....");
              });
  
  
              $(document).on("click", ".kout-edit", null, function (ev) {
                  var current = ko.dataFor(this);
                  current.Mode("edit");
              });
  
              $(document).on("click", ".kout-update", null, function (ev) {
                  var current = ko.dataFor(this);
                  saveData(current);
                  current.Mode("display");
              });
  
              $(document).on("click", ".kout-cancel", null, function (ev) {
                 var current = ko.dataFor(this);
                 current.Mode("display");
              });
  
              $(document).on("click", "#create", null, function (ev) {
                  var current = {
                      Id: ko.observable(0),
                      Key: ko.observable(),
                      Value: ko.observable(),
                      Mode: ko.observable("edit")
                  }
                  viewModel.lookupCollection.push(current);
              });
  
              function saveData(currentData) {
                  var postUrl = "";
                  var submitData = {
                      Id: currentData.Id(),
                      Key: currentData.Key(),
                      Value: currentData.Value()
  
                  };
  
                  if (currentData.Id &amp;&amp; currentData.Id() &gt; 0) {
                      postUrl = "/Home/Edit"
                  }
                  else {
                      postUrl = "/Home/Create"
                  }
                  $.ajax({
                      type: "POST",
                      contentType: "application/json",
                      url: postUrl,
                      data: JSON.stringify(submitData)
                  }).done(function (id) {
                      currentData.Id(id);
                  }).error(function (ex) {
                      alert("ERROR Saving....");
                  })
              }
  
          });
  
      &lt;/script&gt;
  &lt;/head&gt;
  &lt;body&gt;
      &lt;div&gt;
          &lt;p&gt;
              &lt;button class="btn btn-primary" id="create"&gt;Create&lt;/button&gt;
          &lt;/p&gt;
          &lt;table class="table"&gt;
              &lt;tr&gt;
                  &lt;th&gt;Key
                  &lt;/th&gt;
                  &lt;th&gt;Value
                  &lt;/th&gt;
                  &lt;th&gt;Action
                  &lt;/th&gt;
              &lt;/tr&gt;
  
              &lt;tbody data-bind="foreach: lookupCollection"&gt;
                  &lt;tr data-bind="template: { name: Mode, data: $data }"&gt;
                  &lt;/tr&gt;
              &lt;/tbody&gt;
          &lt;/table&gt;
  
          &lt;script type="text/html" id="display"&gt;
              &lt;td data-bind="text: Key"&gt;&lt;/td&gt;
              &lt;td data-bind="text: Value"&gt;&lt;/td&gt;
              &lt;td&gt;
                  &lt;button class="btn btn-success kout-edit"&gt;Edit&lt;/button&gt;
                  &lt;button class="btn btn-danger kout-delete"&gt;Delete&lt;/button&gt;
              &lt;/td&gt;
          &lt;/script&gt;
  
          &lt;script type="text/html" id="edit"&gt;
              &lt;td&gt;
                  &lt;input type="text" data-bind="value: Key" /&gt;&lt;/td&gt;
              &lt;td&gt;
                  &lt;input type="text" data-bind="value: Value" /&gt;&lt;/td&gt;
              &lt;td&gt;
                  &lt;button class="btn btn-success kout-update"&gt;Update&lt;/button&gt;
                  &lt;button class="btn btn-danger kout-cancel"&gt;Cancel&lt;/button&gt;
              &lt;/td&gt;
          &lt;/script&gt;
      &lt;/div&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>