From 14db15b458ff6d5334c55d5b7feefdbe6dc22d92 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Tue, 19 Oct 2010 11:38:53 -0700 Subject: [PATCH] Adding another demo: Todo Task manager --- demos/todos.html | 14 ++++ demos/todos.js | 176 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 190 insertions(+) create mode 100644 demos/todos.html create mode 100644 demos/todos.js diff --git a/demos/todos.html b/demos/todos.html new file mode 100644 index 00000000..993ae22d --- /dev/null +++ b/demos/todos.html @@ -0,0 +1,14 @@ + + + + Backbone Demo: Task Manager + + + + + + + + + + diff --git a/demos/todos.js b/demos/todos.js new file mode 100644 index 00000000..68b78527 --- /dev/null +++ b/demos/todos.js @@ -0,0 +1,176 @@ +(function () { + + // ### Models + + // Our main model. It is simple enough that it doesn't need any prototype + // methods. + var Task = Backbone.Model.extend({}); + + // A Collection wrapper for Task instances. + var TaskCollection = Backbone.Collection.extend({ + model: Task + }); + + // ### Views + + // The TaskView is a View that handles the rendering and events of a single + // Task instance. You can double click on the task's text to edit it's content + // in a text box and tick the checkbox on or off to mark whether it is + // completed or not. + var TaskView = Backbone.View.extend({ + tagName: "li", + events: { + "dblclick span": "edit", + "click input[type=checkbox]": "toggle", + "click input.update": "changed" + }, + + initialize: function (opts) { + this.handleEvents(); // Bind the event delegators. + this.model = opts.model; + }, + + // Render (or empty and re-render) this view. If this task is completed, + // make the text have strike through. + render: function () { + this.$(this.el) + .empty() + .append(this.make("input", { + type: "checkbox", + checked: this.model.get("completed") + })) + .append( + this.$(this.make("span")) + .text(this.model.get("content")) + .css("text-decoration", + this.model.get("completed") + ? "line-through" + : "none") + ); + return this; + }, + + // Switch this view from display mode in to edit mode. Provide a text input + // to edit this task's content and a submit button to click to save the + // updates. + edit: function () { + var input = this.$(this.make("input", { + type: "text", + value: this.$(this.el).text() + })); + var submit = this.$(this.make("input", { + type: "submit", + className: "update", + value: "Update" + })); + this.$(this.el) + .empty() + .append(input) + .append(submit); + }, + + // Switch back to display mode after being in edit mode. Save the new + // content for the model in the process. + changed: function () { + this.model.set({ + content: this.$("input[type=text]").val() + }); + this.render(); + }, + + // Event handler for ticking the checkbox. Just toggle whether the task is + // completed or not and let render() take care of strike-through. + toggle: function () { + this.model.set({ completed: !this.model.get("completed") }); + this.render(); + } + }); + + // The TodoListApp is the main view for this application. It handles creation + // of new Tasks, clearing completed tasks, and supervises the individual + // TaskViews. + var TodoListApp = Backbone.View.extend({ + tagName: "div", + events: { + "click input.new-task" : "create", + "click input.clear" : "clear" + }, + + initialize: function (opts) { + this.handleEvents(); + this.children = opts.children; + }, + + render: function () { + var me = this; + me.$(me.el) + .empty() + .append(me.make("input", { + type: "text", + placeholder: "New task..." + })) + .append(me.make("input", { + className: "new-task", + type: "submit", + value: "Add" + })) + .append(me.make("ul")) + .append(me.make("input", { + type: "submit", + value: "Clear Completed Tasks", + className: "clear" + })); + + // Add a TaskView for each of out tasks. + var list = me.$("ul"); + me.children + .each(function (task) { + var view = new TaskView({ + model: task + }); + list.append(view.render().el); + }); + return this; + }, + + // Create a new task, add it to the children, and let render() handle + // creating a TaskView for it and displaying it. + create: function () { + var task = new Task({ + content: this.$("input[type=text]").val(), + completed: false + }); + this.children.add(task); + this.render(); + }, + + // Clear out all of the completed tasks and let render() handle removing + // them from the page. + clear: function () { + var toBeRemoved = this.children + .filter(function (task) { + return task.get("completed"); + }); + + var me = this; + _(toBeRemoved).each(function (task) { + me.children.remove(task); + }); + + this.render(); + } + }); + + // Initialize the app on document ready. + + $(document).ready(function () { + + var tasks = new TaskCollection; + var app = new TodoListApp({ + children: tasks + }); + $("body").append(app.render().el); + + }); + +}()); \ No newline at end of file