Commit fd14f902 authored by Addy Osmani's avatar Addy Osmani

Merge pull request #43 from boushley/backboneRequire

Fix up Backbone.js with RequireJS
parents dc793dc8 d5ecd818
...@@ -83,6 +83,7 @@ ...@@ -83,6 +83,7 @@
<li><a href="todo-example/javascriptmvc/todo/todo/index.html">JavaScriptMVC</a></li> <li><a href="todo-example/javascriptmvc/todo/todo/index.html">JavaScriptMVC</a></li>
<li><a href="todo-example/spine/index.html">Spine.js</a></li> <li><a href="todo-example/spine/index.html">Spine.js</a></li>
<li><a href="todo-example/backbone/index.html">Backbone.js</a></li> <li><a href="todo-example/backbone/index.html">Backbone.js</a></li>
<li><a href="todo-example/backbone_require/index.html">Backbone.js + RequireJS</a></li>
<li><a href="todo-example/sammyjs/index.html">Sammy.js</a></li> <li><a href="todo-example/sammyjs/index.html">Sammy.js</a></li>
<li><a href="todo-example/knockoutjs/index.html">KnockoutJS (MVVM)</a></li> <li><a href="todo-example/knockoutjs/index.html">KnockoutJS (MVVM)</a></li>
<li><a href="todo-example/yuilibrary/index.html">YUILibrary</a></li> <li><a href="todo-example/yuilibrary/index.html">YUILibrary</a></li>
...@@ -204,4 +205,4 @@ ...@@ -204,4 +205,4 @@
</div> </div>
</body> </body>
</html> </html>
\ No newline at end of file
...@@ -364,7 +364,6 @@ body { ...@@ -364,7 +364,6 @@ body {
width: 170px; width: 170px;
left: 50%; left: 50%;
margin-left: -85px; margin-left: -85px;
opacity: 0;
} }
/* line 55 */ /* line 55 */
#todoapp .content ul#todo-list { #todoapp .content ul#todo-list {
......
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
</div> </div>
<div id="todos"> <div id="todos">
<input class="check mark-all-done" type="checkbox"/>
<label for="check-all">Mark all as complete</label>
<ul id="todo-list"></ul> <ul id="todo-list"></ul>
</div> </div>
......
...@@ -19,10 +19,9 @@ define(['underscore', 'backbone'], function(_, Backbone) { ...@@ -19,10 +19,9 @@ define(['underscore', 'backbone'], function(_, Backbone) {
this.save({done: !this.get("done")}); this.save({done: !this.get("done")});
}, },
// Remove this Todo from *localStorage* and delete its view. // Remove this Todo from *localStorage*.
clear: function() { clear: function() {
this.destroy(); this.destroy();
this.view.remove();
} }
}); });
......
<div class="todo <%= done ? 'done' : '' %>"> <div class="todo <%= done ? 'done' : '' %>">
<div class="display"> <div class="display">
<input class="check" type="checkbox" <%= done ? 'checked="checked"' : '' %> /> <input class="check" type="checkbox" <%= done ? 'checked="checked"' : '' %> />
<div class="todo-content"></div> <div class="todo-content"><%= content %></div>
<span class="todo-destroy"></span> <span class="todo-destroy"></span>
</div> </div>
<div class="edit"> <div class="edit">
<input class="todo-input" type="text" value="" /> <input class="todo-input" type="text" value="<%= content %>" />
</div> </div>
</div> </div>
...@@ -19,16 +19,18 @@ define([ ...@@ -19,16 +19,18 @@ define([
events: { events: {
"keypress #new-todo": "createOnEnter", "keypress #new-todo": "createOnEnter",
"keyup #new-todo": "showTooltip", "keyup #new-todo": "showTooltip",
"click .todo-clear a": "clearCompleted" "click .todo-clear a": "clearCompleted",
"click .mark-all-done": "toggleAllComplete"
}, },
// At initialization we bind to the relevant events on the `Todos` // At initialization we bind to the relevant events on the `Todos`
// collection, when items are added or changed. Kick things off by // collection, when items are added or changed. Kick things off by
// loading any preexisting todos that might be saved in *localStorage*. // loading any preexisting todos that might be saved in *localStorage*.
initialize: function() { initialize: function() {
_.bindAll(this, 'addOne', 'addAll', 'render'); _.bindAll(this, 'addOne', 'addAll', 'render', 'toggleAllComplete');
this.input = this.$("#new-todo"); this.input = this.$("#new-todo");
this.allCheckbox = this.$(".mark-all-done")[0];
Todos.bind('add', this.addOne); Todos.bind('add', this.addOne);
Todos.bind('reset', this.addAll); Todos.bind('reset', this.addAll);
...@@ -41,11 +43,15 @@ define([ ...@@ -41,11 +43,15 @@ define([
// of the app doesn't change. // of the app doesn't change.
render: function() { render: function() {
var done = Todos.done().length; var done = Todos.done().length;
var remaining = Todos.remaining().length;
this.$('#todo-stats').html(this.statsTemplate({ this.$('#todo-stats').html(this.statsTemplate({
total: Todos.length, total: Todos.length,
done: Todos.done().length, done: done,
remaining: Todos.remaining().length remaining: remaining
})); }));
this.allCheckbox.checked = !remaining;
}, },
// Add a single todo item to the list by creating a view for it, and // Add a single todo item to the list by creating a view for it, and
...@@ -93,6 +99,12 @@ define([ ...@@ -93,6 +99,12 @@ define([
if (val == '' || val == this.input.attr('placeholder')) return; if (val == '' || val == this.input.attr('placeholder')) return;
var show = function(){ tooltip.show().fadeIn(); }; var show = function(){ tooltip.show().fadeIn(); };
this.tooltipTimeout = _.delay(show, 1000); this.tooltipTimeout = _.delay(show, 1000);
},
// Change each todo so that it's `done` state matches the check all
toggleAllComplete: function () {
var done = this.allCheckbox.checked;
Todos.each(function (todo) { todo.save({'done': done}); });
} }
}); });
......
...@@ -17,33 +17,24 @@ define([ ...@@ -17,33 +17,24 @@ define([
"click .check" : "toggleDone", "click .check" : "toggleDone",
"dblclick div.todo-content" : "edit", "dblclick div.todo-content" : "edit",
"click span.todo-destroy" : "clear", "click span.todo-destroy" : "clear",
"keypress .todo-input" : "updateOnEnter" "keypress .todo-input" : "updateOnEnter",
"blur .todo-input" : "close"
}, },
// The TodoView listens for changes to its model, re-rendering. Since there's // The TodoView listens for changes to its model, re-rendering. Since there's
// a one-to-one correspondence between a **Todo** and a **TodoView** in this // a one-to-one correspondence between a **Todo** and a **TodoView** in this
// app, we set a direct reference on the model for convenience. // app, we set a direct reference on the model for convenience.
initialize: function() { initialize: function() {
_.bindAll(this, 'render', 'close'); _.bindAll(this, 'render', 'close', 'remove');
this.model.bind('change', this.render); this.model.bind('change', this.render);
this.model.view = this; this.model.bind('destroy', this.remove);
}, },
// Re-render the contents of the todo item. // Re-render the contents of the todo item.
render: function() { render: function() {
$(this.el).html(this.template(this.model.toJSON())); $(this.el).html(this.template(this.model.toJSON()));
this.setContent();
return this;
},
// To avoid XSS (not that it would be harmful in this particular app),
// we use `jQuery.text` to set the contents of the todo item.
setContent: function() {
var content = this.model.get('content');
this.$('.todo-content').text(content);
this.input = this.$('.todo-input'); this.input = this.$('.todo-input');
this.input.bind('blur', this.close); return this;
this.input.val(content);
}, },
// Toggle the `"done"` state of the model. // Toggle the `"done"` state of the model.
...@@ -68,11 +59,6 @@ define([ ...@@ -68,11 +59,6 @@ define([
if (e.keyCode == 13) this.close(); if (e.keyCode == 13) this.close();
}, },
// Remove this view from the DOM.
remove: function() {
$(this.el).remove();
},
// Remove the item, destroy the model. // Remove the item, destroy the model.
clear: function() { clear: function() {
this.model.clear(); this.model.clear();
......
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