An example Backbone application contributed by
+Jérôme Gravel-Niquet. This demo uses a simple
+LocalStorage adapter
+to persist Backbone models within your browser. | |
Load the application once the DOM is ready, using jQuery.ready : | |
Todo Model | |
Our basic Todo model has content , order , and done attributes. | window.Todo = Backbone.Model.extend({ |
If you don't provide a todo, one will be provided for you. | |
Ensure that each todo created has content . | initialize: function() {
if (!this.get("content")) {
this.set({"content": this.EMPTY});
}
- }, |
Toggle the done state of this todo item. | toggle: function() {
+ }, |
Toggle the done state of this todo item. | toggle: function() {
this.save({done: !this.get("done")});
- }, |
Remove this Todo from localStorage, deleting its view. | |
Remove this Todo from localStorage, deleting its view. | clear: function() {
this.destroy();
$(this.view.el).remove();
}
- }); |
Todo Collection | |
The collection of todos is backed by localStorage instead of a remote
-server. | window.TodoList = Backbone.Collection.extend({ |
Reference to this collection's model. | |
Save all of the todo items under the "todos" namespace. | |
Filter down the list of all todo items that are finished. | |
Todo Collection | |
The collection of todos is backed by localStorage instead of a remote
+server. | window.TodoList = Backbone.Collection.extend({ |
Reference to this collection's model. | |
Save all of the todo items under the "todos" namespace. | |
Filter down the list of all todo items that are finished. | done: function() {
return this.filter(function(todo){ return todo.get('done'); });
- }, |
Filter down the list to only todo items that are still not finished. | remaining: function() {
+ }, |
Filter down the list to only todo items that are still not finished. | remaining: function() {
return this.without.apply(this, this.done());
- }, |
We keep the Todos in sequential order, despite being saved by unordered
+ }, |
We keep the Todos in sequential order, despite being saved by unordered
GUID in the database. This generates the next order number for new items. | nextOrder: function() {
if (!this.length) return 1;
return this.last().get('order') + 1;
- }, |
Todos are sorted by their original insertion order. | comparator: function(todo) {
+ }, |
Todos are sorted by their original insertion order. | comparator: function(todo) {
return todo.get('order');
}
- }); |
Create our global collection of Todos. | window.Todos = new TodoList; |
Todo Item View | |
The DOM element for a todo item... | window.TodoView = Backbone.View.extend({ |
... is a list tag. | |
Cache the template function for a single item. | template: _.template($('#item-template').html()), |
The DOM events specific to an item. | |
Create our global collection of Todos. | window.Todos = new TodoList; |
Todo Item View | |
The DOM element for a todo item... | window.TodoView = Backbone.View.extend({ |
... is a list tag. | |
Cache the template function for a single item. | template: _.template($('#item-template').html()), |
The DOM events specific to an item. | events: {
"click .check" : "toggleDone",
"dblclick div.todo-content" : "edit",
"click span.todo-destroy" : "clear",
"keypress .todo-input" : "updateOnEnter"
- }, |
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
app, we set a direct reference on the model for convenience. | initialize: function() {
_.bindAll(this, 'render');
this.model.bind('change', this.render);
this.model.view = this;
- }, |
Re-render the contents of the todo item. | render: function() {
+ }, |
Re-render the contents of the todo item. | render: function() {
$(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),
+ }, |
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.$('.todo-input').val(content);
- }, |
Toggle the "done" state of the model. | toggleDone: function() {
+ }, |
Toggle the "done" state of the model. | toggleDone: function() {
this.model.toggle();
- }, |
Switch this view into "editing" mode, displaying the input field. | |
Switch this view into "editing" mode, displaying the input field. | edit: function() {
$(this.el).addClass("editing");
- }, |
If you hit enter, submit the changes to the todo item's content . | updateOnEnter: function(e) {
+ }, |
If you hit enter, submit the changes to the todo item's content . | updateOnEnter: function(e) {
if (e.keyCode != 13) return;
this.model.save({content: this.$(".todo-input").val()});
$(this.el).removeClass("editing");
- }, |
Remove the item, destroy the model. | |
Remove the item, destroy the model. | clear: function() {
this.model.clear();
}
- }); |
The Application | |
Our overall AppView is the top-level piece of UI. | window.AppView = Backbone.View.extend({ |
Instead of generating a new element, bind to the existing skeleton of
-the App already present in the HTML. | |
Our template for the line of statistics at the bottom of the app. | template: _.template($('#stats-template').html()), |
Delegated events for creating new items, and clearing completed ones. | |
The Application | |
Our overall AppView is the top-level piece of UI. | window.AppView = Backbone.View.extend({ |
Instead of generating a new element, bind to the existing skeleton of
+the App already present in the HTML. | |
Our template for the line of statistics at the bottom of the app. | statsTemplate: _.template($('#stats-template').html()), |
Delegated events for creating new items, and clearing completed ones. | events: {
"keypress #new-todo": "createOnEnter",
"keyup #new-todo": "showTooltip",
"click .todo-clear a": "clearCompleted"
- }, |
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
loading any preexisting todos that might be saved in localStorage. | initialize: function() {
_.bindAll(this, 'addOne', 'addAll', 'render');
@@ -74,35 +74,35 @@
Todos.bind('all', this.render);
Todos.fetch();
- }, |
Re-rendering the App just means refreshing the statistics -- the rest
+ }, |
Re-rendering the App just means refreshing the statistics -- the rest
of the app doesn't change. | render: function() {
var done = Todos.done().length;
- this.$('#todo-stats').html(this.template({
+ this.$('#todo-stats').html(this.statsTemplate({
total: Todos.length,
done: Todos.done().length,
remaining: Todos.remaining().length
}));
- }, |
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
appending its element to the <ul> . | addOne: function(todo) {
var view = new TodoView({model: todo});
this.$("#todo-list").append(view.render().el);
- }, |
Add all items in the Todos collection at once. | addAll: function() {
+ }, |
Add all items in the Todos collection at once. | addAll: function() {
Todos.each(this.addOne);
- }, |
Generate the attributes for a new Todo item. | newAttributes: function() {
+ }, |
Generate the attributes for a new Todo item. | newAttributes: function() {
return {
content: this.input.val(),
order: Todos.nextOrder(),
done: false
};
- }, |
If you hit return in the main input field, create new Todo model,
+ }, |
If you hit return in the main input field, create new Todo model,
persisting it to localStorage. | createOnEnter: function(e) {
if (e.keyCode != 13) return;
Todos.create(this.newAttributes());
this.input.val('');
- }, |
Clear all done todo items, destroying their models. | clearCompleted: function() {
+ }, |
Clear all done todo items, destroying their models. | clearCompleted: function() {
_.each(Todos.done(), function(todo){ todo.clear(); });
return false;
- }, |
Lazily show the tooltip that tells you to press enter to save
+ }, |
Lazily show the tooltip that tells you to press enter to save
a new todo item, after one second. | showTooltip: function(e) {
var tooltip = this.$(".ui-tooltip-top");
var val = this.input.val();
@@ -113,7 +113,7 @@
this.tooltipTimeout = _.delay(show, 1000);
}
- }); |
Finally, we kick things off by creating the App. | window.App = new AppView;
+ }); |
Finally, we kick things off by creating the App. | window.App = new AppView;
});
diff --git a/examples/todos/todos.js b/examples/todos/todos.js
index 18aff7c1a..a8650f976 100644
--- a/examples/todos/todos.js
+++ b/examples/todos/todos.js
@@ -1,4 +1,7 @@
-// Example Backbone App contributed by [Jérôme Gravel-Niquet](http://jgn.me/).
+// An example Backbone application contributed by
+// [Jérôme Gravel-Niquet](http://jgn.me/). This demo uses a simple
+// [LocalStorage adapter](http://github.com/jeromegn/Backbone.localStorage)
+// to persist Backbone models within your browser.
// Load the application once the DOM is ready, using `jQuery.ready`:
$(function(){
@@ -9,10 +12,10 @@ $(function(){
// Our basic **Todo** model has `content`, `order`, and `done` attributes.
window.Todo = Backbone.Model.extend({
+ // If you don't provide a todo, one will be provided for you.
EMPTY: "empty todo...",
- // Ensure that each todo is created with the `content` field filled in, if
- // nothing has been specified.
+ // Ensure that each todo created has `content`.
initialize: function() {
if (!this.get("content")) {
this.set({"content": this.EMPTY});
@@ -151,7 +154,7 @@ $(function(){
el: $("#todoapp"),
// Our template for the line of statistics at the bottom of the app.
- template: _.template($('#stats-template').html()),
+ statsTemplate: _.template($('#stats-template').html()),
// Delegated events for creating new items, and clearing completed ones.
events: {
@@ -179,7 +182,7 @@ $(function(){
// of the app doesn't change.
render: function() {
var done = Todos.done().length;
- this.$('#todo-stats').html(this.template({
+ this.$('#todo-stats').html(this.statsTemplate({
total: Todos.length,
done: Todos.done().length,
remaining: Todos.remaining().length
diff --git a/index.html b/index.html
index 783a45424..1b945038b 100644
--- a/index.html
+++ b/index.html
@@ -1514,81 +1514,24 @@ Backbone.View
Examples
- As a quick example to help get an idea of how Backbone can be used in a
- real-world project, here are the method signatures (beyond the built-in
- methods that Backbone provides) of the Document
- model, and the DocumentSet collection, as used in
- DocumentCloud. In the workspace,
- these classes work together with many others: Project, Note,
- Account, Entity, Organization...
-
-
-
-dc.model.Document = Backbone.Model.extend({
-
- initialize(attributes): ...
-
- canonicalId: ...
-
- url: ...
- viewerUrl: ...
- publishedUrl: ...
- pageThumbnailURL(page): ...
-
- openViewer: ...
- openPublishedViewer: ...
- openText: ...
- openPDF: ...
-
- allowedToEdit: ...
- checkAllowedToEdit(errorMessage): ...
- checkBusy: ...
-
- uniquePageEntities: ...
-
- isPending: ...
- isPublic: ...
- isPublished: ...
-
- toString: ...
-
-});
-
-
-dc.model.DocumentSet = Backbone.Collection.extend({
-
- model: dc.model.Document,
-
- url: '/documents',
-
- initialize(options): ...
-
- comparator(document): ...
-
- selectAll: ...
- deselectAll: ...
- selectedIds: ...
-
- filterPending: ...
- filterSelected: ...
-
- getCommonAttribute(documents, attribute): ...
-
- allowedToEdit(documents, errorMessage): ...
- editAccess(documents): ...
-
- downloadSelectedViewers: ...
- downloadSelectedPDFs: ...
- downloadSelectedTexts: ...
-
- poll: ...
- startPolling: ...
- stopPolling: ...
-
- verifyDestroy(documents): ...
-
-});
-
+ Jérôme Gravel-Niquet has contributed a
+ Todo List application
+ that is bundled in the repository as Backbone example. If you're wondering
+ where to get started with Backbone in general, take a moment to
+ read through the annotated source. The app uses a
+ LocalStorage adapter
+ to transparently save all of your todos within your browser, instead of
+ sending them to a server. Jérôme also has a version hosted at
+ localtodos.com that uses a
+ MooTools-backed version of Backbone
+ instead of jQuery.
+
+
+
Change Log
|