Download BackBone.js File
BackBone.js GitHub Repository
https://github.com/jashkenas/backbone
Upload Static Resource
- backbone.js
- jquery.js
- underscore.js
BackBoneJsTaskApp.page
<apex:page title="Backbone.js" showHeader="true" sidebar="false"> <apex:include pageName="BackBoneJsTaskAppCss" /> <div id="vf-page"> <h1>Tasks</h1> <form id="addTask"> <input type="text" id="title" /> <input type="submit" value="add" /> <span id="error"></span> </form> <div id="tasks"></div> <p>Tasks Count: <span id='count'></span></p> <script type="text/template" id="task-template"> <input type="checkbox" class="toggle" <%= completed ? 'checked': '' %>></input> <span class="<%= completed ? 'completed' : '' %>"> <%- title %> <span class="delete">[x]</span> </span> </script> </div> <apex:includeScript value="{!URLFOR($Resource.BackBoneJS, 'js/underscore.js')}" /> <apex:includeScript value="{!URLFOR($Resource.BackBoneJS, 'js/jquery.js')}" /> <apex:includeScript value="{!URLFOR($Resource.BackBoneJS, 'js/backbone.js')}" /> <apex:include pageName="BackBoneJsTaskAppScript"/> </apex:page>
BackBoneJsTaskAppScript.page
<apex:page > <script type="text/javascript"> (function() { // Model var Task = Backbone.Model.extend({ defaults: { title: 'do something', completed: false }, validate: function(attrs) { if ( _.isEmpty(attrs.title)) { return 'title must not be empty'; } }, initialize: function() { this.on('invalid', function(model, error) { $('#error').html(error); }) } }); var Tasks = Backbone.Collection.extend({ model: Task}); // View var TaskView = Backbone.View.extend({ tagName: 'li', initialize: function() { this.model.on('destroy', this.remove, this); this.model.on('change', this.render, this); }, events: { 'click .delete': 'destroy', 'click .toggle': 'toggle' }, toggle: function() { this.model.set('completed', !this.model.get('completed')); }, destroy: function() { if (confirm('are you sure?')) { this.model.destroy(); } }, remove: function() { this.$el.remove(); }, template: _.template($('#task-template').html()), render: function() { var template = this.template(this.model.toJSON()); this.$el.html(template); return this; } }); var TasksView = Backbone.View.extend({ tagName: 'ul', initialize: function() { this.collection.on('add', this.addNew, this); this.collection.on('change', this.updateCount, this); this.collection.on('destroy', this.updateCount, this); }, addNew: function(task) { var taskView = new TaskView({model: task}); this.$el.append(taskView.render().el); $('#title').val('').focus(); this.updateCount(); }, updateCount: function() { var uncompletedTasks = this.collection.filter(function(task) { return !task.get('completed'); }); $('#count').html(uncompletedTasks.length); }, render: function() { this.collection.each(function(task) { var taskView = new TaskView({model: task}); this.$el.append(taskView.render().el); }, this); this.updateCount(); return this; } }); var AddTaskView = Backbone.View.extend({ el : '#addTask', events: { 'submit': 'submit' }, submit: function(e) { e.preventDefault(); //var task = new Task({title: $('#title').val()}); var task = new Task(); if (task.set({title: $('#title').val()}, {validate: true})) { this.collection.add(task); $('#error').empty(); } } }); var tasks = new Tasks([ { title: 'task1', completed: true }, { title: 'task2' }, { title: 'task3' } ]); var tasksView = new TasksView({collection: tasks}); var addTaskView = new AddTaskView({collection: tasks}); $('#tasks').html(tasksView.render().el); })(); </script> </apex:page>
BackBoneJsTaskAppCss.page
<apex:page > <style type="text/css"> #vf-page * { font-family: 'メイリオ', sans-serif; font-size: 18px; } #vf-page input[type=text] { font-size: 14px; padding: 5px; width: 200px; } #vf-page ul li { list-style-type: none; } #vf-page .completed { text-decoration: line-through; color: gray; } #error { color: red; } </style> </apex:page>
No comments:
Post a Comment