Commit 49acf173 authored by Ryan Niemeyer's avatar Ryan Niemeyer

Add "Mark all as complete" checkbox bound to a writeable computed observable...

Add "Mark all as complete" checkbox bound to a writeable computed observable and minor code cleanup.
parent 3560728d
...@@ -15,6 +15,10 @@ ...@@ -15,6 +15,10 @@
<span class="ui-tooltip-top" style="display: none;">Press Enter to save this task</span> <span class="ui-tooltip-top" style="display: none;">Press Enter to save this task</span>
</div> </div>
<div id="todos"> <div id="todos">
<div data-bind="visible: todos().length">
<input id="check-all" class="check" type="checkbox" data-bind="checked: allCompleted" />
<label for="check-all">Mark all as complete</label>
</div>
<ul id="todo-list" data-bind="foreach: todos"> <ul id="todo-list" data-bind="foreach: todos">
<li data-bind="css: { editing: editing }"> <li data-bind="css: { editing: editing }">
<div class="todo" data-bind="css: { done : done }"> <div class="todo" data-bind="css: { done : done }">
......
...@@ -40,51 +40,66 @@ ...@@ -40,51 +40,66 @@
var ViewModel = function(todos) { var ViewModel = function(todos) {
var self = this; var self = this;
//map array of passed in todos to an observableArray of Todo objects //map array of passed in todos to an observableArray of Todo objects
this.todos = ko.observableArray(ko.utils.arrayMap(todos, function(todo) { self.todos = ko.observableArray(ko.utils.arrayMap(todos, function(todo) {
return new Todo(todo.content, todo.done); return new Todo(todo.content, todo.done);
})); }));
//store the new todo value being entered //store the new todo value being entered
this.current = ko.observable(); self.current = ko.observable();
//add a new todo, when enter key is pressed //add a new todo, when enter key is pressed
this.add = function (data, event) { self.add = function (data, event) {
var newTodo = new Todo(self.current()); var newTodo = new Todo(self.current());
self.todos.push(newTodo); self.todos.push(newTodo);
self.current(""); self.current("");
}; };
//remove a single todo //remove a single todo
this.remove = function (todo) { self.remove = function (todo) {
self.todos.remove(todo); self.todos.remove(todo);
}; };
//remove all completed todos //remove all completed todos
this.removeCompleted = function () { self.removeCompleted = function () {
self.todos.remove(function(todo) { self.todos.remove(function(todo) {
return todo.done(); return todo.done();
}); });
}; };
//count of all completed todos //count of all completed todos
this.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) {
return todo.done(); return todo.done();
}).length; }).length;
}); });
//count of todos that are not complete //count of todos that are not complete
this.remainingCount = ko.computed(function () { self.remainingCount = ko.computed(function () {
return self.todos().length - self.completedCount(); return self.todos().length - self.completedCount();
}); });
//writeable computed observable to handle marking all complete/incomplete
self.allCompleted = ko.computed({
//always return true/false based on the done flag of all todos
read: function() {
return !self.remainingCount();
},
//set all todos to the written value (true/false)
write: function(newValue) {
ko.utils.arrayForEach(self.todos(), function(todo) {
//set even if value is the same, as subscribers are not notified in that case
todo.done(newValue);
});
}
});
//helper function to keep expressions out of markup //helper function to keep expressions out of markup
this.getLabel = function(count) { self.getLabel = function(count) {
return ko.utils.unwrapObservable(count) === 1 ? "item" : "items"; return ko.utils.unwrapObservable(count) === 1 ? "item" : "items";
}; };
//computed observable that fires whenever anything changes in our todos //internal computed observable that fires whenever anything changes in our todos
this.isDirty = ko.computed(function() { ko.computed(function() {
//get a clean copy of the todos, which also creates a dependency on the observableArray and all observables in each item //get a clean copy of the todos, which also creates a dependency on the observableArray and all observables in each item
var todos = ko.toJS(self.todos); var todos = ko.toJS(self.todos);
......
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