Double click to edit example

Ryan Niemeyer's ko.revertibleObservable with bootstrap and ESC´n´CRLF-control

by Asle Gundersby

HTML

<script src="http://netdna.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div class="container">
    <div class="row"> <span class="textbatch title" data-bind="visible: !isEditing(),text: asletitle, doubleClick: editItem"></span>

        <input class="title-textbatch form-control" data-bind="visible: isEditing(), textInput: asletitle.forEditing, event:{keyup: $root.update}" />
    </div>
</div>

JavaScript

ko.revertibleObservable = function (initialValue) {
      //private variables
      var result = ko.observable(initialValue);

      result.forEditing = ko.observable(initialValue);

      //if different, commit edit value
      result.commit = function () {
          var editValue = result.forEditing();

          if (editValue !== result()) {
              result(editValue);
          }
      };

      //force subscribers to take original
      result.reset = function () {
          result.forEditing(result());
      };

      return result;
  };

  ko.bindingHandlers.doubleClick = {
      init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
          var handler = valueAccessor(),
              delay = 200,
              clickTimeout = false;

          $(element).click(function (e) {
              if (clickTimeout !== false) {
                  handler.call(this, bindingContext.$data, e);
                  clickTimeout = false;
                  e.stopPropagation(); //This will only cause singleclick to stopPropagation as well, meaning the accordion item won´t expand/collaps when single clicking.
                  e.preventDefault();
              } else {
                  clickTimeout = setTimeout(function () {
                      clickTimeout = false;
                  }, delay);
              }
          });
      }
  };


  ViewModel = function () {
      var self = this;

      self.asletitle = ko.revertibleObservable("DOUBLE CLICK me to edit");

      // edit an item
      self.isEditing = ko.observable(false);

      self.editItem = function () {
          self.isEditing(true);
      };
      // stop editing an item. 
      self.stopEditing = function () {
          self.isEditing(false);
      };
      self.editCommit = function () {
          self.asletitle.commit();
          self.isEditing(false);
      };
      self.editReset = function () {
          self.asletitle.reset();
          self.isEditing(false);
...