Skip to content
Browse files

Updated the todo for jmvc examples

  • Loading branch information...
1 parent 04d97be commit d13cecdb297ac9db699201af7d926a8526f3893c @andykant andykant committed Jul 28, 2012
Showing with 246 additions and 243 deletions.
  1. +0 −98 todo/model.js
  2. +0 −5 todo/styles/todo.css
  3. +6 −0 todo/{styles/base.css → todo.css}
  4. +25 −0 todo/todo.ejs
  5. +18 −18 todo/todo.html
  6. +197 −97 todo/todo.js
  7. +0 −25 todo/views/todo.ejs
View
98 todo/model.js
@@ -1,98 +0,0 @@
-steal('can/model',
- 'jquery/lang/json').then(function() {
-
- // Basic Todo entry model
- // { text: 'todo', complete: false }
- can.Model('Todo', {
-
- // Implement local storage handling
- localStore: function(cb){
- var name = 'todos-jmvc',
- data = $.evalJSON( window.localStorage[name] || (window.localStorage[name] = '[]') ),
- res = cb.call(this, data);
- if(res !== false){
- can.each(data, function(i, todo) {
- delete todo.editing;
- });
- window.localStorage[name] = $.toJSON(data);
- }
- },
-
- findAll: function(params){
- var def = new can.Deferred();
- this.localStore(function(todos){
- var instances = [],
- self = this;
- can.each(todos, function(todo, i) {
- instances.push(new self(todo));
- });
- def.resolve({data: instances});
- })
- return def;
- },
-
- destroy: function(id){
- var def = new can.Deferred();
- this.localStore(function(todos){
- for (var i = 0; i < todos.length; i++) {
- if (todos[i].id === id) {
- todos.splice(i, 1);
- break;
- }
- }
- def.resolve({});
- });
- return def
- },
-
- create: function(attrs){
- var def = new can.Deferred();
- this.localStore(function(todos){
- attrs.id = attrs.id || parseInt(100000 *Math.random());
- todos.push(attrs);
- });
- def.resolve({id : attrs.id});
- return def
- },
-
- update: function(id, attrs){
- var def = new can.Deferred();
- this.localStore(function(todos){
- for (var i = 0; i < todos.length; i++) {
- if (todos[i].id === id) {
- var todo = todos[i];
- break;
- }
- }
- can.extend(todo, attrs);
- });
- def.resolve({});
- return def
- }
-
- },{});
-
- // List for Todos
- can.Model.List('Todo.List', {
-
- completed: function() {
- // Ensure this triggers on length change
- this.attr('length');
-
- var completed = 0;
- this.each(function(todo, i) {
- completed += todo.attr('complete') ? 1 : 0
- });
- return completed;
- },
-
- remaining: function() {
- return this.attr('length') - this.completed();
- },
-
- allComplete: function() {
- return this.attr('length') === this.completed();
- }
- });
-
-});
View
5 todo/styles/todo.css
@@ -1,5 +0,0 @@
-#main.show,
-#stats.show,
-#stats.show #clear-completed {
- display: block;
-}
View
6 todo/styles/base.css → todo/todo.css
@@ -205,4 +205,10 @@ body {
#credits a {
color: #888;
+}
+
+#main.show,
+#stats.show,
+#stats.show #clear-completed {
+ display: block;
}
View
25 todo/todo.ejs
@@ -0,0 +1,25 @@
+<section id="main" class="<%= todos.attr("length") > 0 ? "show" : "" %>">
+ <input id="toggle-all" type="checkbox" <%= todos.allComplete() ? "checked" : "" %>>
+ <label for="toggle-all">Mark all as complete</label>
+ <ul id="todo-list">
+ <% list(todos, function( todo ) { %>
+ <li class="todo
+ <%= todo.attr("complete") ? "done" : "" %>
+ <%= todo.attr("editing") ? "editing" : "" %>"
+ <%= (el)-> el.data('todo', todo) %>>
+ <div class="view">
+ <input class="toggle" type="checkbox" <%= todo.attr("complete") ? "checked" : "" %>>
+ <label><%= todo.attr("text") %></label>
+ <a class="destroy"></a>
+ </div>
+ <input class="edit" type="text" value="<%= todo.attr("text") %>">
+ </li>
+ <% }) %>
+ </ul>
+</section>
+<footer id="stats" class="<%= todos.attr("length") > 0 ? "show" : "" %>">
+ <a id="clear-completed">Clear <%= todos.completed() %>
+ completed item<%= todos.completed() == 1 ? "" : "s" %></a>
+ <div id="todo-count"><span><%= todos.remaining() %></span>
+ item<%= todos.remaining() == 1 ? "" : "s" %> left</div>
+</footer>
View
36 todo/todo.html
@@ -1,25 +1,25 @@
<!doctype html>
<html lang="en">
<head>
- <meta charset="utf-8">
- <title>Todo - JavaScriptMVC 3.3</title>
- <!--[if lt IE 9]>
- <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
- <![endif]-->
+ <meta charset="utf-8">
+ <title>Todo - JavaScriptMVC 3.3</title>
+ <!--[if lt IE 9]>
+ <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
+ <![endif]-->
</head>
<body>
- <div id="todoapp">
- <header>
- <h1>Todos</h1>
- <input id="new-todo" type="text" placeholder="What needs to be done?">
- </header>
- </div>
- <div id="instructions">
- Double-click to edit a todo.
- </div>
- <div id="credits">
- Created by <a href="http://bitovi.com/">Bitovi</a>.
- </div>
- <script src="../steal/steal.js?todo,development"></script>
+ <div id="todoapp">
+ <header>
+ <h1>Todos</h1>
+ <input id="new-todo" type="text" placeholder="What needs to be done?">
+ </header>
+ </div>
+ <div id="instructions">
+ Double-click to edit a todo.
+ </div>
+ <div id="credits">
+ Created by <a href="http://bitovi.com/">Bitovi</a>.
+ </div>
+ <script src="../steal/steal.js?todo,development"></script>
</body>
</html>
View
294 todo/todo.js
@@ -1,99 +1,199 @@
-steal('can/control', 'can/view/ejs')
- .then('./model.js',
- './styles/base.css',
- './styles/todo.css')
- .then(function() {
-
- can.Control('Todos', {
-
- // Initialize the Todos list
- init : function(){
- // Render the Todos
- this.element.append(can.view('//todo/views/todo.ejs', {
- todos: this.options.todos
- }));
-
- // Clear the new todo field
- $('#new-todo').val('').focus();
- },
-
- // Listen for when a new Todo has been entered
- '#new-todo keyup' : function(el, ev){
- if(ev.keyCode == 13){
- new Todo({
- text : el.val(),
- complete : false
- }).save(function() {
- el.val('');
- });
- }
- },
-
- // Handle a newly created Todo
- '{Todo} created' : function(list, ev, item){
- this.options.todos.push(item);
- },
-
- // Listen for editing a Todo
- '.todo dblclick' : function(el, ev) {
- el.data('todo').attr('editing', true).save(function() {
- el.children('.edit').focus().select();
- });
- },
-
- // Update a todo
- updateTodo: function(el) {
- el.closest('.todo').data('todo')
- .attr({
- editing: false,
- text: el.val()
- }).save();
- },
-
- // Listen for an edited Todo
- '.todo .edit keyup' : function(el, ev){
- if(ev.keyCode == 13){
- this.updateTodo(el);
- }
- },
- '.todo .edit focusout' : function(el, ev) {
- this.updateTodo(el);
- },
-
- // Listen for the toggled completion of a Todo
- '.todo .toggle click' : function(el, ev) {
- el.closest('.todo').data('todo')
- .attr('complete', el.is(':checked'))
- .save();
- },
-
- // Listen for a removed Todo
- '.todo .destroy click' : function(el){
- el.closest('.todo').data('todo').destroy();
- },
-
- // Listen for toggle all completed Todos
- '#toggle-all click' : function(el, ev) {
- var toggle = el.prop('checked');
- can.each(this.options.todos, function(i, todo) {
- todo.attr('complete', toggle).save();
- });
- },
-
- // Listen for removing all completed Todos
- '#clear-completed click' : function() {
- for (var i = this.options.todos.length - 1, todo; i > -1 && (todo = this.options.todos[i]); i--) {
- todo.attr('complete') && todo.destroy();
- }
- }
-
- })
-
- // Initialize the app
- Todo.findAll({}, function(todos) {
- new Todos('#todoapp', {
- todos: todos
- });
- });
+steal('can/model', 'can/control', 'can/view/ejs', 'jquery/lang/json')
+ .then('./todo.css')
+ .then(function() {
+
+ // Basic Todo entry model
+ // { text: 'todo', complete: false }
+ can.Model('Todo', {
+
+ /**
+ * Gets JSON data from localStorage. Any changes that
+ * get made in cb get written back to localStorage.
+ *
+ * This is unimportant for understanding JavaScriptMVC!
+ */
+ localStore: function(cb){
+ var name = 'todos-jmvc',
+ data = $.evalJSON( window.localStorage[name] || (window.localStorage[name] = '[]') ),
+ res = cb.call(this, data);
+ if(res !== false){
+ can.each(data, function(i, todo) {
+ delete todo.editing;
+ });
+ window.localStorage[name] = $.toJSON(data);
+ }
+ },
+
+ findAll: function(params){
+ var def = new can.Deferred();
+ this.localStore(function(todos){
+ var instances = [],
+ self = this;
+ can.each(todos, function(todo, i) {
+ instances.push(new self(todo));
+ });
+ def.resolve({data: instances});
+ })
+ return def;
+ },
+
+ destroy: function(id){
+ var def = new can.Deferred();
+ this.localStore(function(todos){
+ for (var i = 0; i < todos.length; i++) {
+ if (todos[i].id === id) {
+ todos.splice(i, 1);
+ break;
+ }
+ }
+ def.resolve({});
+ });
+ return def
+ },
+
+ create: function(attrs){
+ var def = new can.Deferred();
+ this.localStore(function(todos){
+ attrs.id = attrs.id || parseInt(100000 *Math.random());
+ todos.push(attrs);
+ });
+ def.resolve({id : attrs.id});
+ return def
+ },
+
+ update: function(id, attrs){
+ var def = new can.Deferred();
+ this.localStore(function(todos){
+ for (var i = 0; i < todos.length; i++) {
+ if (todos[i].id === id) {
+ var todo = todos[i];
+ break;
+ }
+ }
+ can.extend(todo, attrs);
+ });
+ def.resolve({});
+ return def
+ }
+
+ },{});
+
+ // List for Todos
+ can.Model.List('Todo.List', {
+
+ /**
+ * Returns the number of completed todos
+ */
+ completed: function() {
+ // Ensure this triggers on length change
+ this.attr('length');
+
+ var completed = 0;
+ this.each(function(todo, i) {
+ completed += todo.attr('complete') ? 1 : 0
+ });
+ return completed;
+ },
+
+ remaining: function() {
+ return this.attr('length') - this.completed();
+ },
+
+ allComplete: function() {
+ return this.attr('length') === this.completed();
+ }
+ });
+
+ can.Control('Todos', {
+
+ // Initialize the Todos list
+ init : function(){
+ // Render the Todos
+ this.element.append(can.view('//todo/todo.ejs', {
+ todos: this.options.todos
+ }));
+
+ // Clear the new todo field
+ $('#new-todo').val('').focus();
+ },
+
+ // Listen for when a new Todo has been entered
+ '#new-todo keyup' : function(el, ev){
+ if(ev.keyCode == 13){
+ new Todo({
+ text : el.val(),
+ complete : false
+ }).save(function() {
+ el.val('');
+ });
+ }
+ },
+
+ // Handle a newly created Todo
+ '{Todo} created' : function(list, ev, item){
+ this.options.todos.push(item);
+ },
+
+ // Listen for editing a Todo
+ '.todo dblclick' : function(el, ev) {
+ el.data('todo').attr('editing', true).save(function() {
+ el.children('.edit').focus().select();
+ });
+ },
+
+ // Update a todo
+ updateTodo: function(el) {
+ el.closest('.todo').data('todo')
+ .attr({
+ editing: false,
+ text: el.val()
+ }).save();
+ },
+
+ // Listen for an edited Todo
+ '.todo .edit keyup' : function(el, ev){
+ if(ev.keyCode == 13){
+ this.updateTodo(el);
+ }
+ },
+ '.todo .edit focusout' : function(el, ev) {
+ this.updateTodo(el);
+ },
+
+ // Listen for the toggled completion of a Todo
+ '.todo .toggle click' : function(el, ev) {
+ el.closest('.todo').data('todo')
+ .attr('complete', el.is(':checked'))
+ .save();
+ },
+
+ // Listen for a removed Todo
+ '.todo .destroy click' : function(el){
+ el.closest('.todo').data('todo').destroy();
+ },
+
+ // Listen for toggle all completed Todos
+ '#toggle-all click' : function(el, ev) {
+ var toggle = el.prop('checked');
+ can.each(this.options.todos, function(i, todo) {
+ todo.attr('complete', toggle).save();
+ });
+ },
+
+ // Listen for removing all completed Todos
+ '#clear-completed click' : function() {
+ for (var i = this.options.todos.length - 1, todo; i > -1 && (todo = this.options.todos[i]); i--) {
+ todo.attr('complete') && todo.destroy();
+ }
+ }
+
+ });
+
+ // Initialize the app
+ Todo.findAll({}, function(todos) {
+ new Todos('#todoapp', {
+ todos: todos
+ });
+ });
});
View
25 todo/views/todo.ejs
@@ -1,25 +0,0 @@
-<section id="main" class="<%= todos.attr("length") > 0 ? "show" : "" %>">
- <input id="toggle-all" type="checkbox" <%= todos.allComplete() ? "checked" : "" %>>
- <label for="toggle-all">Mark all as complete</label>
- <ul id="todo-list">
- <% list(todos, function( todo ) { %>
- <li class="todo
- <%= todo.attr("complete") ? "done" : "" %>
- <%= todo.attr("editing") ? "editing" : "" %>"
- <%= (el)-> el.data('todo', todo) %>>
- <div class="view">
- <input class="toggle" type="checkbox" <%= todo.attr("complete") ? "checked" : "" %>>
- <label><%= todo.attr("text") %></label>
- <a class="destroy"></a>
- </div>
- <input class="edit" type="text" value="<%= todo.attr("text") %>">
- </li>
- <% }) %>
- </ul>
-</section>
-<footer id="stats" class="<%= todos.attr("length") > 0 ? "show" : "" %>">
- <a id="clear-completed">Clear <%= todos.completed() %>
- completed item<%= todos.completed() == 1 ? "" : "s" %></a>
- <div id="todo-count"><span><%= todos.remaining() %></span>
- item<%= todos.remaining() == 1 ? "" : "s" %> left</div>
-</footer>

0 comments on commit d13cecd

Please sign in to comment.
Something went wrong with that request. Please try again.