Commit 77201888 authored by Dave Methvin's avatar Dave Methvin Committed by Sam Saccone

typescript-angular: Add ability to abandon edits with Esc key

Ref #789

This roughly follows the pattern in examples/angularjs which already had the
ability to use Esc.
parent 7d6eb896
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
<button class="destroy" ng-click="vm.removeTodo(todo)"></button> <button class="destroy" ng-click="vm.removeTodo(todo)"></button>
</div> </div>
<form ng-submit="vm.doneEditing(todo)"> <form ng-submit="vm.doneEditing(todo)">
<input class="edit" ng-model="todo.title" todo-blur="vm.doneEditing(todo)" todo-focus="todo == editedTodo"> <input class="edit" ng-model="todo.title" todo-blur="vm.doneEditing(todo)" todo-focus="todo == editedTodo" todo-escape="vm.revertEdits(todo)">
</form> </form>
</li> </li>
</ul> </ul>
......
...@@ -53,6 +53,28 @@ var todos; ...@@ -53,6 +53,28 @@ var todos;
})(todos || (todos = {})); })(todos || (todos = {}));
/// <reference path='../_all.ts' /> /// <reference path='../_all.ts' />
var todos; var todos;
(function (todos) {
'use strict';
var ESCAPE_KEY = 27;
/**
* Directive that cancels editing a todo if the user presses the Esc key.
*/
function todoEscape() {
return {
link: function ($scope, element, attributes) {
element.bind('keydown', function (event) {
if (event.keyCode === ESCAPE_KEY) {
$scope.$apply(attributes.todoEscape);
}
});
$scope.$on('$destroy', function () { element.unbind('keydown'); });
}
};
}
todos.todoEscape = todoEscape;
})(todos || (todos = {}));
/// <reference path='../_all.ts' />
var todos;
(function (todos_1) { (function (todos_1) {
'use strict'; 'use strict';
/** /**
...@@ -125,9 +147,21 @@ var todos; ...@@ -125,9 +147,21 @@ var todos;
}; };
TodoCtrl.prototype.editTodo = function (todoItem) { TodoCtrl.prototype.editTodo = function (todoItem) {
this.$scope.editedTodo = todoItem; this.$scope.editedTodo = todoItem;
// Clone the original todo in case editing is cancelled.
this.$scope.originalTodo = angular.extend({}, todoItem);
};
TodoCtrl.prototype.revertEdits = function (todoItem) {
this.todos[this.todos.indexOf(todoItem)] = this.$scope.originalTodo;
this.$scope.reverted = true;
}; };
TodoCtrl.prototype.doneEditing = function (todoItem) { TodoCtrl.prototype.doneEditing = function (todoItem) {
this.$scope.editedTodo = null; this.$scope.editedTodo = null;
this.$scope.originalTodo = null;
if (this.$scope.reverted) {
// Todo edits were reverted, don't save.
this.$scope.reverted = null;
return;
}
todoItem.title = todoItem.title.trim(); todoItem.title = todoItem.title.trim();
if (!todoItem.title) { if (!todoItem.title) {
this.removeTodo(todoItem); this.removeTodo(todoItem);
...@@ -169,6 +203,7 @@ var todos; ...@@ -169,6 +203,7 @@ var todos;
.controller('todoCtrl', todos.TodoCtrl) .controller('todoCtrl', todos.TodoCtrl)
.directive('todoBlur', todos.todoBlur) .directive('todoBlur', todos.todoBlur)
.directive('todoFocus', todos.todoFocus) .directive('todoFocus', todos.todoFocus)
.directive('todoEscape', todos.todoEscape)
.service('todoStorage', todos.TodoStorage); .service('todoStorage', todos.TodoStorage);
})(todos || (todos = {})); })(todos || (todos = {}));
/// <reference path='libs/jquery/jquery.d.ts' /> /// <reference path='libs/jquery/jquery.d.ts' />
...@@ -178,6 +213,7 @@ var todos; ...@@ -178,6 +213,7 @@ var todos;
/// <reference path='interfaces/ITodoStorage.ts' /> /// <reference path='interfaces/ITodoStorage.ts' />
/// <reference path='directives/TodoFocus.ts' /> /// <reference path='directives/TodoFocus.ts' />
/// <reference path='directives/TodoBlur.ts' /> /// <reference path='directives/TodoBlur.ts' />
/// <reference path='directives/TodoEscape.ts' />
/// <reference path='services/TodoStorage.ts' /> /// <reference path='services/TodoStorage.ts' />
/// <reference path='controllers/TodoCtrl.ts' /> /// <reference path='controllers/TodoCtrl.ts' />
/// <reference path='Application.ts' /> /// <reference path='Application.ts' />
......
...@@ -12,5 +12,6 @@ module todos { ...@@ -12,5 +12,6 @@ module todos {
.controller('todoCtrl', TodoCtrl) .controller('todoCtrl', TodoCtrl)
.directive('todoBlur', todoBlur) .directive('todoBlur', todoBlur)
.directive('todoFocus', todoFocus) .directive('todoFocus', todoFocus)
.directive('todoEscape', todoEscape)
.service('todoStorage', TodoStorage); .service('todoStorage', TodoStorage);
} }
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
/// <reference path='interfaces/ITodoStorage.ts' /> /// <reference path='interfaces/ITodoStorage.ts' />
/// <reference path='directives/TodoFocus.ts' /> /// <reference path='directives/TodoFocus.ts' />
/// <reference path='directives/TodoBlur.ts' /> /// <reference path='directives/TodoBlur.ts' />
/// <reference path='directives/TodoEscape.ts' />
/// <reference path='services/TodoStorage.ts' /> /// <reference path='services/TodoStorage.ts' />
/// <reference path='controllers/TodoCtrl.ts' /> /// <reference path='controllers/TodoCtrl.ts' />
/// <reference path='Application.ts' /> /// <reference path='Application.ts' />
...@@ -74,10 +74,24 @@ module todos { ...@@ -74,10 +74,24 @@ module todos {
editTodo(todoItem: TodoItem) { editTodo(todoItem: TodoItem) {
this.$scope.editedTodo = todoItem; this.$scope.editedTodo = todoItem;
// Clone the original todo in case editing is cancelled.
this.$scope.originalTodo = angular.extend({}, todoItem);
}
revertEdits(todoItem: TodoItem) {
this.todos[this.todos.indexOf(todoItem)] = this.$scope.originalTodo;
this.$scope.reverted = true;
} }
doneEditing(todoItem: TodoItem) { doneEditing(todoItem: TodoItem) {
this.$scope.editedTodo = null; this.$scope.editedTodo = null;
this.$scope.originalTodo = null;
if (this.$scope.reverted) {
// Todo edits were reverted, don't save.
this.$scope.reverted = null;
return;
}
todoItem.title = todoItem.title.trim(); todoItem.title = todoItem.title.trim();
if (!todoItem.title) { if (!todoItem.title) {
this.removeTodo(todoItem); this.removeTodo(todoItem);
......
/// <reference path='../_all.ts' />
module todos {
'use strict';
const ESCAPE_KEY = 27;
/**
* Directive that cancels editing a todo if the user presses the Esc key.
*/
export function todoEscape(): ng.IDirective {
return {
link: ($scope: ng.IScope, element: JQuery, attributes: any) => {
element.bind('keydown', (event) => {
if (event.keyCode === ESCAPE_KEY) {
$scope.$apply(attributes.todoEscape);
}
});
$scope.$on('$destroy', () => { element.unbind('keydown'); });
}
};
}
}
...@@ -5,9 +5,11 @@ module todos { ...@@ -5,9 +5,11 @@ module todos {
todos: TodoItem[]; todos: TodoItem[];
newTodo: string; newTodo: string;
editedTodo: TodoItem; editedTodo: TodoItem;
originalTodo: TodoItem;
remainingCount: number; remainingCount: number;
doneCount: number; doneCount: number;
allChecked: boolean; allChecked: boolean;
reverted: boolean;
statusFilter: { completed: boolean; }; statusFilter: { completed: boolean; };
location: ng.ILocationService; location: ng.ILocationService;
vm: TodoCtrl; vm: TodoCtrl;
......
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