Commit 4116c09d authored by Ryan Niemeyer's avatar Ryan Niemeyer

Update Knockout.js sample to use 2.0.0 features.

parent a02ee13c
...@@ -3,9 +3,7 @@ ...@@ -3,9 +3,7 @@
<head> <head>
<title>Knockout.js</title> <title>Knockout.js</title>
<link href="css/todos.css" media="all" rel="stylesheet" type="text/css" /> <link href="css/todos.css" media="all" rel="stylesheet" type="text/css" />
<script src="js/jquery-1.6.1.js" type="text/javascript"></script> <script src="js/knockout-2.0.0.js" type="text/javascript"></script>
<script src="js/jquery.tmpl.js" type="text/javascript"></script>
<script src="js/knockout-1.2.1.js" type="text/javascript"></script>
</head> </head>
<body> <body>
<div id="todoapp"> <div id="todoapp">
...@@ -14,20 +12,41 @@ ...@@ -14,20 +12,41 @@
</div> </div>
<div class="content"> <div class="content">
<div id="create-todo"> <div id="create-todo">
<input id="new-todo" data-bind="value: current, event: { keyup: add}" placeholder="What needs to be done?" <input id="new-todo" data-bind="value: current, valueUpdate: 'afterkeydown', event: { keyup: add }" placeholder="What needs to be done?" />
type="text" />
<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">
<ul id="todo-list" data-bind="template: { name: 'todoitemtemplate', foreach: todos }"> <ul id="todo-list" data-bind="foreach: todos">
<li data-bind="css: { editing: editing }">
<div class="todo" data-bind="css: { done : done }">
<div class="display">
<input class="check" type="checkbox" data-bind="checked: done" />
<div class="todo-content" data-bind="text: content, event: { dblclick: edit }" style="cursor: pointer;"></div>
<span class="todo-destroy" data-bind="click: $root.remove"></span>
</div>
<div class="edit">
<input class="todo-input" data-bind="value: content, valueUpdate: 'afterkeydown', event: { keyup: editkeyup, blur: stopEditing }"/>
</div>
</div>
</li>
</ul> </ul>
</div> </div>
<div id="todo-stats" data-bind="template: { name: 'statstemplate'}"> <div id="todo-stats">
<span class="todo-count" data-bind="visible: remainingCount">
<span class="number" data-bind="text: remainingCount"></span>
<span class="word" data-bind="text: getLabel(remainingCount)"></span> left.
</span>
<span class="todo-clear" data-bind="visible: completedCount">
<a href="#" data-bind="click: removeCompleted">
Clear <span class="number-done" data-bind="text: completedCount"></span>
completed <span class="word-done" data-bind="text: getLabel(completedCount)"></span>
</a>
</span>
</div> </div>
</div> </div>
</div> </div>
<ul id="instructions"> <ul id="instructions">
<li>Double-click to edit a todo.</li> <li data-bind="visible: todos().length">Double-click to edit a todo.</li>
</ul> </ul>
<div id="credits"> <div id="credits">
Created by Created by
...@@ -37,96 +56,84 @@ ...@@ -37,96 +56,84 @@
Modified to use knockout.js by Modified to use knockout.js by
<br /> <br />
<a href="https://github.com/ashish01/knockoutjs-todos">Ashish Sharma</a> <a href="https://github.com/ashish01/knockoutjs-todos">Ashish Sharma</a>
<br /> <br/>
Patches/fixes for cross-browser compat: Updated to use knockout.js 2.0 by
<br/>
<a href="http://knockmeout.net">Ryan Niemeyer</a>
<br />
Patches/fixes for cross-browser compat:
<br /> <br />
<a href="http://twitter.com/addyosmani">Addy Osmani</a> <a href="http://twitter.com/addyosmani">Addy Osmani</a>
</div> </div>
<script id="todoitemtemplate" type="text/html">
<li data-bind="css: {editing: editing}">
<div data-bind="attr: { class : done() ? 'todo done' : 'todo'}">
<div class="display">
<input class="check" type="checkbox" data-bind="checked: done" />
<div class="todo-content" data-bind="text: content, click: edit" style="cursor: pointer;"></div>
<span class="todo-destroy" data-bind="click: viewModel.remove"></span>
</div>
<div class="edit">
<input class="todo-input" type="text" data-bind="value: content, event: { keyup: editkeyup, blur: stopEditing }"/>
</div>
</div>
</li>
</script>
<script id="statstemplate" type="text/html">
<span class="todo-count" data-bind="visible: remaining().length > 0">
<span class="number" data-bind="text: remaining().length"></span>
<span class="word" data-bind="text: remaining().length == 1 ? 'item' : 'items'"></span> left.
</span>
<span class="todo-clear" data-bind="visible: done().length > 0">
<a href="#" data-bind="click: removeCompleted">
Clear <span class="number-done" data-bind="text: done().length"></span>
completed <span class="word-done"data-bind="text: done().length == 1 ? 'item' : 'items'"></span>
</a>
</span>
</script>
<script type="text/javascript"> <script type="text/javascript">
var Todo = function (text) { (function() {
this.content = ko.observable(text); //represent a single todo item
this.order = ko.observable(); var Todo = function (text) {
this.done = ko.observable(false); this.content = ko.observable(text);
this.editing = ko.observable(false); this.done = ko.observable(false);
this.edit = function() { this.editing(true); }; this.editing = ko.observable(false);
this.stopEditing = function() { this.editing(false); }; };
this.editkeyup = function(event) {
if (event.keyCode === 13) {
this.stopEditing();
}
};
}
var viewModel = {
todos: ko.observableArray(),
current: ko.observable(),
add: function (event) {
if (event.keyCode === 13) {
var todoContent = "";
/*includes fix for Opera*/
(viewModel.current() == undefined) ? todoContent = $('#new-todo').val() : todoContent = viewModel.current();
var newTodo = new Todo(todoContent);
this.todos.push(newTodo);
this.current("");
//can place methods on prototype, as there can be many todos
ko.utils.extend(Todo.prototype, {
edit: function() { this.editing(true); },
stopEditing: function() { this.editing(false); },
editkeyup: function(data, event) {
if (event.keyCode === 13) {
this.stopEditing();
}
} }
});
}, //our main view model
var ViewModel = function() {
var self = this;
this.todos = ko.observableArray();
this.current = ko.observable();
remove: function (event) { //add a new todo, when enter key is pressed
viewModel.todos.remove(this); this.add = function (data, event) {
}, if (event.keyCode === 13) {
var newTodo = new Todo(self.current());
self.todos.push(newTodo);
self.current("");
}
};
removeCompleted: function (event) { //remove a single todo
viewModel.todos.removeAll(viewModel.done()); this.remove = function (todo) {
} self.todos.remove(todo);
}; };
//remove all completed todos
this.removeCompleted = function () {
self.todos.remove(function(todo) {
return todo.done();
});
};
viewModel.remaining = ko.dependentObservable(function () { //count of all completed todos
return this.todos().filter(function (el) { this.completedCount = ko.computed(function () {
return el.done() === false; return ko.utils.arrayFilter(self.todos(), function(todo) {
}); return todo.done();
}, viewModel), }).length;
});
viewModel.done = ko.dependentObservable(function () { //count of todos that are not complete
return this.todos().filter(function (el) { this.remainingCount = ko.computed(function () {
return el.done() === true; return self.todos().length - self.completedCount();
}); });
}, viewModel),
//helper function to keep expressions out of markup
this.getLabel = function(count) {
return ko.utils.unwrapObservable(count) === 1 ? "item" : "items";
};
};
ko.applyBindings(viewModel); //bind a new instance of our view model to the page
ko.applyBindings(new ViewModel());
})();
</script> </script>
</body> </body>
</html> </html>
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
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