Commit f50d5507 authored by Sam Saccone's avatar Sam Saccone

Merge pull request #1530 from dmethvin/kjs-require

knockoutjs_require: Cancel edits using Escape key
parents 77201888 d9abbdbd
......@@ -22,7 +22,7 @@
<label data-bind="text: title, event: { dblclick: $root.editItem }"></label>
<button class="destroy" data-bind="click: $root.remove"></button>
</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>
</ul>
</section>
......
......@@ -4,5 +4,6 @@
define({
ENTER_KEY: 13,
ESCAPE_KEY: 27,
localStorageItem: 'todos-knockout-require'
});
......@@ -6,30 +6,33 @@ define([
], function (ko, g) {
'use strict';
// a custom binding to handle the enter key (could go in a separate library)
ko.bindingHandlers.enterKey = {
init: function (element, valueAccessor, allBindingsAccessor, data, bindingContext) {
var wrappedHandler;
var newValueAccessor;
function keyupBindingFactory(keyCode) {
return {
init: function (element, valueAccessor, allBindingsAccessor, data, bindingContext) {
var wrappedHandler, newValueAccessor;
// wrap the handler with a check for the enter key
wrappedHandler = function (data, event) {
if (event.keyCode === g.ENTER_KEY) {
valueAccessor().call(this, data, event);
}
};
// wrap the handler with a check for the enter key
wrappedHandler = function (data, event) {
if (event.keyCode === keyCode) {
valueAccessor().call(this, data, event);
}
};
// create a valueAccessor with the options that we would want to pass to the event binding
newValueAccessor = function () {
return {
keyup: wrappedHandler
// create a valueAccessor with the options that we would want to pass to the event binding
newValueAccessor = function () {
return {
keyup: wrappedHandler
};
};
};
// call the real event binding's init function
ko.bindingHandlers.event.init(element, newValueAccessor, allBindingsAccessor, data, bindingContext);
}
};
// call the real event binding's init function
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
ko.bindingHandlers.selectAndFocus = {
......
......@@ -44,6 +44,7 @@ define([
// edit an item
self.editItem = function (item) {
item.editing(true);
item.previousTitle = item.title();
};
// stop editing an item. Remove the item, if it is now empty
......@@ -54,7 +55,7 @@ define([
var trimmedTitle = title.trim();
// Observable value changes are not triggered if they're consisting of whitespaces only
// Therefore we've to compare untrimmed version with a trimmed one to chech whether anything changed
// Therefore, compare untrimmed version with a trimmed one to check whether anything changed
// And if yes, we've to set the new value manually
if (title !== trimmedTitle) {
item.title(trimmedTitle);
......@@ -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
self.completedCount = ko.computed(function () {
return ko.utils.arrayFilter(self.todos(), function (todo) {
......@@ -99,7 +106,8 @@ define([
// internal computed observable that fires whenever anything changes in our todos
ko.computed(function () {
// store a clean copy to local storage, which also creates a dependency on the observableArray and all observables in each item
// store a clean copy to local storage, which also creates a dependency
// on the observableArray and all observables in each item
window.localStorage.setItem(g.localStorageItem, ko.toJSON(self.todos));
}).extend({
rateLimit: { timeout: 500, method: 'notifyWhenChangesStop' }
......
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