diff --git a/labs/architecture-examples/epitome/bower.json b/labs/architecture-examples/epitome/bower.json index 82adbb2fe0..af4e6aa26f 100644 --- a/labs/architecture-examples/epitome/bower.json +++ b/labs/architecture-examples/epitome/bower.json @@ -2,7 +2,7 @@ "name": "todomvc-epitome", "version": "0.0.0", "dependencies": { - "epitome": "0.3.1", - "todomvc-common": "~0.1.6" + "todomvc-common": "~0.1.6", + "Epitome": "~0.3.1" } } diff --git a/labs/architecture-examples/epitome/index.html b/labs/architecture-examples/epitome/index.html index 2dbe4688c1..c39b049818 100644 --- a/labs/architecture-examples/epitome/index.html +++ b/labs/architecture-examples/epitome/index.html @@ -22,19 +22,21 @@

todos

- + diff --git a/labs/architecture-examples/epitome/js/app.js b/labs/architecture-examples/epitome/js/app.js index 2bd39167c9..7207108eb0 100644 --- a/labs/architecture-examples/epitome/js/app.js +++ b/labs/architecture-examples/epitome/js/app.js @@ -1,17 +1,16 @@ -/*global Epitome */ /*jshint mootools:true */ -(function( window ) { +(function (window) { 'use strict'; var App = window.App; - var todos = new App.TodoCollection( null, { + var todos = new App.TodoCollection(null, { // a consistent collection if is needed if you want to use storage for a collection id: 'todos' }); // populate from storage if available - todos.setUp( todos.retrieve() ); + todos.setUp(todos.retrieve()); // instantiate the todo list view App.todoView = new App.TodoView({ @@ -20,10 +19,10 @@ collection: todos, // encapsulating element to bind to - element: document.id( 'todo-list' ), + element: document.id('todo-list'), // template to use - template: document.id( 'item-template' ).get( 'text' ) + template: document.id('item-template').get('text') }); @@ -37,11 +36,11 @@ element: document.id('todoapp'), // stats template from DOM - template: document.id( 'stats-template' ).get( 'text' ), + template: document.id('stats-template').get('text'), - onReady: function() { + onReady: function () { // need to work with controller that sets the current state of filtering - var proxy = function() { + var proxy = function () { App.router.showActiveFilter(); }; @@ -57,12 +56,12 @@ '#!/:filter': 'applyFilter' }, - onInit: function() { + onInit: function () { // we want to always have a state - this.navigate( '#!/' ); + this.navigate('#!/'); }, - onApplyFilter: function( filter ) { + onApplyFilter: function (filter) { // the filter is being used by the todo collection and view. // when false, the whole collection is being passed. todos.filterType = filter || false; @@ -73,4 +72,4 @@ this.showActiveFilter(); } }); -}( window )); +})(window); diff --git a/labs/architecture-examples/epitome/js/collections/todo-collection.js b/labs/architecture-examples/epitome/js/collections/todo-collection.js index 7242a441dc..acf927a609 100644 --- a/labs/architecture-examples/epitome/js/collections/todo-collection.js +++ b/labs/architecture-examples/epitome/js/collections/todo-collection.js @@ -1,6 +1,6 @@ /*global Epitome, App */ /*jshint mootools:true */ -(function(window) { +(function (window) { 'use strict'; window.App = window.App || {}; @@ -21,9 +21,9 @@ completed: 1 }, - todoFilter: function( model ) { + todoFilter: function (model) { // references the filterType which the controller sets - return this.filterType === false ? true : this.map[this.filterType] === +model.get( 'completed' ); + return this.filterType === false ? true : this.map[this.filterType] === +model.get('completed'); } }); -}( window )); +})(window); diff --git a/labs/architecture-examples/epitome/js/controllers/todo-router.js b/labs/architecture-examples/epitome/js/controllers/todo-router.js index ff99d982a1..66f5950ad7 100644 --- a/labs/architecture-examples/epitome/js/controllers/todo-router.js +++ b/labs/architecture-examples/epitome/js/controllers/todo-router.js @@ -1,6 +1,6 @@ /*global Epitome, App */ /*jshint mootools:true */ -(function(window) { +(function (window) { 'use strict'; window.App = window.App || {}; @@ -9,14 +9,14 @@ Extends: Epitome.Router, - showActiveFilter: function() { + showActiveFilter: function () { // fix up the links for current filter var self = this; - document.getElements( '#filters li a' ).each(function( link ) { - link.set( 'class', link.get( 'href' ) === self.req ? 'selected' : '' ); + document.getElements('#filters li a').each(function (link) { + link.set('class', link.get('href') === self.req ? 'selected' : ''); }); } }); -}( window )); +})(window); diff --git a/labs/architecture-examples/epitome/js/models/todo-model.js b/labs/architecture-examples/epitome/js/models/todo-model.js index d0da624946..8acaa6e74b 100644 --- a/labs/architecture-examples/epitome/js/models/todo-model.js +++ b/labs/architecture-examples/epitome/js/models/todo-model.js @@ -1,6 +1,6 @@ /*global Epitome, App */ /*jshint mootools:true */ -(function(window) { +(function (window) { 'use strict'; window.App = window.App || {}; @@ -28,4 +28,4 @@ model: App.Todo }); -}( window )); +})(window); diff --git a/labs/architecture-examples/epitome/js/views/todo-list.js b/labs/architecture-examples/epitome/js/views/todo-list.js index c24a7a32af..d3ab7c635d 100644 --- a/labs/architecture-examples/epitome/js/views/todo-list.js +++ b/labs/architecture-examples/epitome/js/views/todo-list.js @@ -1,6 +1,6 @@ /*global Epitome, App */ /*jshint mootools:true */ -(function( window ) { +(function (window) { 'use strict'; window.App = window.App || {}; @@ -29,89 +29,91 @@ }, // define actual event handlers - onReady: function() { + onReady: function () { // initial view this.render(); }, // when collection changes, save the data to storage and re-render - 'onChange:collection': function( model ) { + 'onChange:collection': function () { this.collection.store(); this.render(); }, // when models get removed, re-render - 'onRemove:collection': function( model ) { + 'onRemove:collection': function () { this.collection.store(); this.render(); }, // when sort is applied, re-render - 'onSort:collection': function() { + 'onSort:collection': function () { this.collection.store(); this.render(); }, // when a new model is added, re-render - 'onAdd:collection': function( model ) { + 'onAdd:collection': function () { this.collection.store(); this.render(); }, // handler for the edit event - onEditing: function( e, el ) { - if ( e && e.stop ) { + onEditing: function (e, el) { + if (e && e.stop) { e.stop(); } var container = el.getParent('li'); - container.addClass( this.options.editingClass ); - container.getElement( this.options.input ).focus(); + var input = container.getElement(this.options.input); + + container.addClass(this.options.editingClass); + input.focus(); + input.value = input.value; }, // when enter pressed while editing - onHandleKeypress: function( e, el ) { + onHandleKeypress: function (e, el) { // on enter, blur() and let it bubble to onUpdate. - if ( e.key === 'enter' ) { + if (e.key === 'enter') { el.blur(); } }, - // fired when editing ends - onUpdate: function( e, el ) { - var p = el.getParent( 'li ').removeClass( this.options.editingClass ); - var val = el.get( 'value' ).trim(); + onUpdate: function (e, el) { + var p = el.getParent('li').removeClass(this.options.editingClass); + var val = el.get('value').trim(); - if ( !val.length ) { + if (!val.length) { // the render method stores the model into the element, get it and remove - this.collection.removeModel( p.retrieve( 'model' ) ); + this.collection.removeModel(p.retrieve('model')); return; } - p.retrieve( 'model' ).set( 'title', val ); + p.retrieve('model').set('title', val); }, // handler for clicks on the checkboxes - onStatusChange: function( e, el ) { - var p = el.getParent( 'li' ); - var done = !!el.get( 'checked' ); + onStatusChange: function (e, el) { + var p = el.getParent('li'); + var done = !!el.get('checked'); - p.retrieve( 'model' ).set( 'completed', done ); + p.retrieve('model').set('completed', done); }, // when the X is pressed, drop the model - onRemoveItem: function( e, el ) { - if ( e && e.stop ) { + onRemoveItem: function (e, el) { + if (e && e.stop) { e.stop(); } // the render method stores the model into the element, get it and remove - this.collection.removeModel( el.getParent( 'li' ).retrieve( 'model' ) ); + this.collection.removeModel(el.getParent('li').retrieve('model')); } }, - render: function() { + render: function () { // main render method, will also fire onRender var todos = new Elements(); var self = this; @@ -120,23 +122,23 @@ this.empty(); // the route controller works with the todoFilter to help determine what we render. - this.collection.filter( this.collection.todoFilter.bind( this.collection ) ).each(function( model ) { + this.collection.filter(this.collection.todoFilter.bind(this.collection)).each(function (model) { var obj = model.toJSON(); - var li = new Element( self.tagName ).toggleClass( 'completed', obj.completed ).store( 'model', model ); + var li = new Element(self.tagName).toggleClass('completed', obj.completed).store('model', model); // help the template to avoid slower logic in the template layer obj.completedCheckbox = obj.completed ? 'checked' : ''; // compile template and store resulting element in our Elements collection - todos.push( li.set( 'html', self.template( obj ) ) ); + todos.push(li.set('html', self.template(obj))); }); // inject the elements collection into the container element - this.element.adopt( todos ); + this.element.adopt(todos); // propagate the render event. this.parent(); return this; } }); -}( window )); +})(window); diff --git a/labs/architecture-examples/epitome/js/views/todo-main.js b/labs/architecture-examples/epitome/js/views/todo-main.js index 7a540d734b..304722badd 100644 --- a/labs/architecture-examples/epitome/js/views/todo-main.js +++ b/labs/architecture-examples/epitome/js/views/todo-main.js @@ -1,6 +1,6 @@ /*global Epitome, App */ /*jshint mootools:true */ -(function( window ) { +(function (window) { 'use strict'; window.App = window.App || {}; @@ -25,70 +25,77 @@ footer: 'footer', + main: 'main', + filters: '#filters li a', toggleAll: 'toggle-all', - onToggleAll: function( e, el ) { + onToggleAll: function (e, el) { // all todos will change their models to the new completed value - var state = !!el.get( 'checked' ); - this.collection.each( function( model ) { - model.set( 'completed', state ); + var state = !!el.get('checked'); + this.collection.each(function (model) { + model.set('completed', state); }); }, - onHandleKeypress: function( e, el ) { + onHandleKeypress: function (e) { // on enter, submit. - if ( e.key === 'enter' ) { + if (e.key === 'enter') { this.addTodo(); } }, - onClearCompleted: function() { + onClearCompleted: function () { // because removing a model re-indexes so we don't get a sparse array, cannot apply that in a normal loop. - var toRemove = this.collection.filter(function( model ) { - return model.get( 'completed' ); + var toRemove = this.collection.filter(function (model) { + return model.get('completed'); }); // removeModel actually supports a single model or an array of models as arguments. - this.collection.removeModel( toRemove ); + this.collection.removeModel(toRemove); this.render(); }, - onAddTodo: function() { + onAddTodo: function () { // go to method this.addTodo(); }, - 'onChange:collection': function() { + 'onChange:collection': function () { // also, re-render on change of collection this.render(); }, - 'onAdd:collection': function() { + 'onRemove:collection': function () { + this.render(); + }, + + 'onAdd:collection': function () { // when adding, re-render. this.render(); } }, - initialize: function( options ) { + initialize: function (options) { // call default view constructor. - this.parent( options ); + this.parent(options); // store some pointers to static elements - this.newTodo = document.id( this.options.newTodo ); - this.footer = document.id( this.options.footer ); - this.toggleAll = document.id( this.options.toggleAll ); + this.newTodo = document.id(this.options.newTodo); + this.footer = document.id(this.options.footer); + this.toggleAll = document.id(this.options.toggleAll); + this.main = document.id(this.options.main); // draw it. this.render(); }, - addTodo: function() { + addTodo: function () { // adding a new model when data exists - var val = this.newTodo.get( 'value' ).trim(); + var val = this.newTodo.get('value').trim(); - if ( val.length ) { + if (val.length) { this.collection.addModel({ title: val, completed: false @@ -96,33 +103,37 @@ } // clear the input - this.newTodo.set( 'value', '' ); + this.newTodo.set('value', ''); }, - render: function() { + render: function () { // main method to output everything. well. the footer anyway. // work out what we have remaining and what is complete var remaining = 0; - var completed = this.collection.filter(function( model ) { - var status = model.get( 'completed' ); + var completed = this.collection.filter(function (model) { + var status = model.get('completed'); - if ( status === false ) { + if (status === false) { remaining++; } return status; }).length; + var visibleClass = remaining || completed ? '' : 'hidden'; + // output footer - this.footer.set( 'html', this.template({ + this.footer.set('html', this.template({ completed: completed, remaining: remaining - })); + })).set('class', visibleClass); + + this.main.set('class', visibleClass); // auto-correct the toggle-all checkbox with the new stats. - this.toggleAll.set( 'checked', this.collection.length ? !remaining : false ); + this.toggleAll.set('checked', this.collection.length ? !remaining : false); } }); -}( window )); +})(window);