Commit 03fb6318 authored by Dave Methvin's avatar Dave Methvin

knockoutjs_require: Cancel edits using Escape key

Ref #789

Design pattern and some code taken from examples/requirejs.
parent 69cb6f7c
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
<label data-bind="text: title, event: { dblclick: $root.editItem }"></label> <label data-bind="text: title, event: { dblclick: $root.editItem }"></label>
<button class="destroy" data-bind="click: $root.remove"></button> <button class="destroy" data-bind="click: $root.remove"></button>
</div> </div>
<input class="edit" data-bind="value: title, valueUpdate: 'afterkeydown', enterKey: $root.stopEditing, selectAndFocus: editing, event: { blur: $root.stopEditing }"> <input class="edit" data-bind="value: title, valueUpdate: 'afterkeydown', enterKey: $root.stopEditing, escapeKey: $root.cancelEditing, selectAndFocus: editing, event: { blur: $root.stopEditing }">
</li> </li>
</ul> </ul>
</section> </section>
......
...@@ -4,5 +4,6 @@ ...@@ -4,5 +4,6 @@
define({ define({
ENTER_KEY: 13, ENTER_KEY: 13,
ESCAPE_KEY: 27,
localStorageItem: 'todos-knockout-require' localStorageItem: 'todos-knockout-require'
}); });
...@@ -6,30 +6,33 @@ define([ ...@@ -6,30 +6,33 @@ define([
], function (ko, g) { ], function (ko, g) {
'use strict'; 'use strict';
// a custom binding to handle the enter key (could go in a separate library) function keyupBindingFactory(keyCode) {
ko.bindingHandlers.enterKey = { return {
init: function (element, valueAccessor, allBindingsAccessor, data, bindingContext) { init: function (element, valueAccessor, allBindingsAccessor, data, bindingContext) {
var wrappedHandler; var wrappedHandler, newValueAccessor;
var newValueAccessor;
// wrap the handler with a check for the enter key // wrap the handler with a check for the enter key
wrappedHandler = function (data, event) { wrappedHandler = function (data, event) {
if (event.keyCode === g.ENTER_KEY) { if (event.keyCode === keyCode) {
valueAccessor().call(this, data, event); valueAccessor().call(this, data, event);
} }
}; };
// create a valueAccessor with the options that we would want to pass to the event binding // create a valueAccessor with the options that we would want to pass to the event binding
newValueAccessor = function () { newValueAccessor = function () {
return { return {
keyup: wrappedHandler keyup: wrappedHandler
};
}; };
};
// call the real event binding's init function // call the real event binding's init function
ko.bindingHandlers.event.init(element, newValueAccessor, allBindingsAccessor, data, bindingContext); ko.bindingHandlers.event.init(element, newValueAccessor, allBindingsAccessor, data, bindingContext);
} }
}; };
}
ko.bindingHandlers.enterKey = keyupBindingFactory(g.ENTER_KEY);
ko.bindingHandlers.escapeKey = keyupBindingFactory(g.ESCAPE_KEY);
// wrapper to hasfocus that also selects text and applies focus async // wrapper to hasfocus that also selects text and applies focus async
ko.bindingHandlers.selectAndFocus = { ko.bindingHandlers.selectAndFocus = {
......
...@@ -44,6 +44,7 @@ define([ ...@@ -44,6 +44,7 @@ define([
// edit an item // edit an item
self.editItem = function (item) { self.editItem = function (item) {
item.editing(true); item.editing(true);
item.previousTitle = item.title();
}; };
// stop editing an item. Remove the item, if it is now empty // stop editing an item. Remove the item, if it is now empty
...@@ -65,6 +66,12 @@ define([ ...@@ -65,6 +66,12 @@ define([
} }
}; };
// cancel editing an item and revert to the previous content
self.cancelEditing = function (item) {
item.editing(false);
item.title(item.previousTitle);
};
// count of all completed todos // count of all completed todos
self.completedCount = ko.computed(function () { self.completedCount = ko.computed(function () {
return ko.utils.arrayFilter(self.todos(), function (todo) { return ko.utils.arrayFilter(self.todos(), function (todo) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment