Commit f0c582c3 authored by Sindre Sorhus's avatar Sindre Sorhus

Merge pull request #462 from passy/style-update

Style update for Backbone and Ember
parents 879f666c ad8a026c
/*global $*/
/*jshint unused:false*/
var app = app || {};
var ENTER_KEY = 13;
$(function() {
$(function () {
'use strict';
// Kick things off by creating the **App**.
new app.AppView();
......
/*global Backbone Store*/
var app = app || {};
(function() {
(function () {
'use strict';
// Todo Collection
......@@ -17,28 +18,28 @@ var app = app || {};
localStorage: new Store('todos-backbone'),
// Filter down the list of all todo items that are finished.
completed: function() {
return this.filter(function( todo ) {
completed: function () {
return this.filter(function (todo) {
return todo.get('completed');
});
},
// Filter down the list to only todo items that are still not finished.
remaining: function() {
return this.without.apply( this, this.completed() );
remaining: function () {
return this.without.apply(this, this.completed());
},
// 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 ) {
nextOrder: function () {
if (!this.length) {
return 1;
}
return this.last().get('order') + 1;
},
// Todos are sorted by their original insertion order.
comparator: function( todo ) {
comparator: function (todo) {
return todo.get('order');
}
});
......
/*global Backbone*/
var app = app || {};
(function() {
(function () {
'use strict';
// Todo Model
......@@ -17,7 +18,7 @@ var app = app || {};
},
// Toggle the `completed` state of this todo item.
toggle: function() {
toggle: function () {
this.save({
completed: !this.get('completed')
});
......
/*global Backbone*/
var app = app || {};
(function() {
(function () {
'use strict';
// Todo Router
// ----------
var Workspace = Backbone.Router.extend({
routes:{
routes: {
'*filter': 'setFilter'
},
setFilter: function( param ) {
setFilter: function (param) {
// Set the current filter to be used
app.TodoFilter = param.trim() || '';
......
/*global Backbone _ $ ENTER_KEY*/
var app = app || {};
$(function( $ ) {
$(function ($) {
'use strict';
// The Application
......@@ -14,7 +15,7 @@ $(function( $ ) {
el: '#todoapp',
// Our template for the line of statistics at the bottom of the app.
statsTemplate: _.template( $('#stats-template').html() ),
statsTemplate: _.template($('#stats-template').html()),
// Delegated events for creating new items, and clearing completed ones.
events: {
......@@ -26,7 +27,7 @@ $(function( $ ) {
// 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() {
initialize: function () {
this.allCheckbox = this.$('#toggle-all')[0];
this.$input = this.$('#new-todo');
this.$footer = this.$('#footer');
......@@ -43,11 +44,11 @@ $(function( $ ) {
// Re-rendering the App just means refreshing the statistics -- the rest
// of the app doesn't change.
render: function() {
render: function () {
var completed = app.Todos.completed().length;
var remaining = app.Todos.remaining().length;
if ( app.Todos.length ) {
if (app.Todos.length) {
this.$main.show();
this.$footer.show();
......@@ -58,7 +59,7 @@ $(function( $ ) {
this.$('#filters li a')
.removeClass('selected')
.filter('[href="#/' + ( app.TodoFilter || '' ) + '"]')
.filter('[href="#/' + (app.TodoFilter || '') + '"]')
.addClass('selected');
} else {
this.$main.hide();
......@@ -70,27 +71,27 @@ $(function( $ ) {
// Add a single todo item to the list by creating a view for it, and
// appending its element to the `<ul>`.
addOne: function( todo ) {
addOne: function (todo) {
var view = new app.TodoView({ model: todo });
$('#todo-list').append( view.render().el );
$('#todo-list').append(view.render().el);
},
// Add all items in the **Todos** collection at once.
addAll: function() {
addAll: function () {
this.$('#todo-list').html('');
app.Todos.each(this.addOne, this);
},
filterOne: function( todo ) {
filterOne: function (todo) {
todo.trigger('visible');
},
filterAll: function() {
filterAll: function () {
app.Todos.each(this.filterOne, this);
},
// Generate the attributes for a new Todo item.
newAttributes: function() {
newAttributes: function () {
return {
title: this.$input.val().trim(),
order: app.Todos.nextOrder(),
......@@ -100,25 +101,25 @@ $(function( $ ) {
// If you hit return in the main input field, create new **Todo** model,
// persisting it to *localStorage*.
createOnEnter: function( e ) {
if ( e.which !== ENTER_KEY || !this.$input.val().trim() ) {
createOnEnter: function (e) {
if (e.which !== ENTER_KEY || !this.$input.val().trim()) {
return;
}
app.Todos.create( this.newAttributes() );
app.Todos.create(this.newAttributes());
this.$input.val('');
},
// Clear all completed todo items, destroying their models.
clearCompleted: function() {
clearCompleted: function () {
_.invoke(app.Todos.completed(), 'destroy');
return false;
},
toggleAllComplete: function() {
toggleAllComplete: function () {
var completed = this.allCheckbox.checked;
app.Todos.each(function( todo ) {
app.Todos.each(function (todo) {
todo.save({
'completed': completed
});
......
/*global Backbone _ $ ENTER_KEY*/
var app = app || {};
$(function() {
$(function () {
'use strict';
// Todo Item View
......@@ -13,7 +14,7 @@ $(function() {
tagName: 'li',
// Cache the template function for a single item.
template: _.template( $('#item-template').html() ),
template: _.template($('#item-template').html()),
// The DOM events specific to an item.
events: {
......@@ -27,50 +28,50 @@ $(function() {
// 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() {
initialize: function () {
this.listenTo(this.model, 'change', this.render);
this.listenTo(this.model, 'destroy', this.remove);
this.listenTo(this.model, 'visible', this.toggleVisible);
},
// Re-render the titles of the todo item.
render: function() {
this.$el.html( this.template( this.model.toJSON() ) );
this.$el.toggleClass( 'completed', this.model.get('completed') );
render: function () {
this.$el.html(this.template(this.model.toJSON()));
this.$el.toggleClass('completed', this.model.get('completed'));
this.toggleVisible();
this.$input = this.$('.edit');
return this;
},
toggleVisible: function() {
this.$el.toggleClass( 'hidden', this.isHidden());
toggleVisible: function () {
this.$el.toggleClass('hidden', this.isHidden());
},
isHidden: function() {
isHidden: function () {
var isCompleted = this.model.get('completed');
return ( // hidden cases only
(!isCompleted && app.TodoFilter === 'completed')
|| (isCompleted && app.TodoFilter === 'active')
return (// hidden cases only
(!isCompleted && app.TodoFilter === 'completed') ||
(isCompleted && app.TodoFilter === 'active')
);
},
// Toggle the `"completed"` state of the model.
toggleCompleted: function() {
toggleCompleted: function () {
this.model.toggle();
},
// Switch this view into `"editing"` mode, displaying the input field.
edit: function() {
edit: function () {
this.$el.addClass('editing');
this.$input.focus();
},
// Close the `"editing"` mode, saving changes to the todo.
close: function() {
close: function () {
var value = this.$input.val().trim();
if ( value ) {
if (value) {
this.model.save({ title: value });
} else {
this.clear();
......@@ -80,14 +81,14 @@ $(function() {
},
// If you hit `enter`, we're through editing the item.
updateOnEnter: function( e ) {
if ( e.which === ENTER_KEY ) {
updateOnEnter: function (e) {
if (e.which === ENTER_KEY) {
this.close();
}
},
// Remove the item, destroy the model from *localStorage* and delete its view.
clear: function() {
clear: function () {
this.model.destroy();
}
});
......
/*global Ember*/
window.Todos = Ember.Application.create();
/*global Todos Ember*/
'use strict';
Todos.TodoController = Ember.ObjectController.extend({
isEditing: false,
editTodo: function() {
editTodo: function () {
this.set('isEditing', true);
},
removeTodo: function() {
removeTodo: function () {
var todo = this.get('model');
todo.deleteRecord();
......
/*global Todos Ember*/
'use strict';
Todos.TodosController = Ember.ArrayController.extend({
createTodo: function() {
createTodo: function () {
// Get the todo title set by the "New Todo" text field
var title = this.get('newTitle');
if (!title.trim()) { return; }
......@@ -17,38 +20,38 @@ Todos.TodosController = Ember.ArrayController.extend({
this.get('store').commit();
},
clearCompleted: function() {
clearCompleted: function () {
var completed = this.filterProperty('isCompleted', true);
completed.invoke('deleteRecord');
this.get('store').commit();
},
remaining: function() {
return this.filterProperty( 'isCompleted', false ).get( 'length' );
}.property( '@each.isCompleted' ),
remaining: function () {
return this.filterProperty('isCompleted', false).get('length');
}.property('@each.isCompleted'),
remainingFormatted: function() {
remainingFormatted: function () {
var remaining = this.get('remaining');
var plural = remaining === 1 ? 'item' : 'items';
return '<strong>%@</strong> %@ left'.fmt(remaining, plural);
}.property('remaining'),
completed: function() {
completed: function () {
return this.filterProperty('isCompleted', true).get('length');
}.property('@each.isCompleted'),
hasCompleted: function() {
hasCompleted: function () {
return this.get('completed') > 0;
}.property('completed'),
allAreDone: function( key, value ) {
if ( value !== undefined ) {
this.setEach( 'isCompleted', value );
allAreDone: function (key, value) {
if (value !== undefined) {
this.setEach('isCompleted', value);
return value;
} else {
return !!this.get( 'length' ) &&
this.everyProperty( 'isCompleted', true );
return !!this.get('length') &&
this.everyProperty('isCompleted', true);
}
}.property( '@each.isCompleted' )
}.property('@each.isCompleted')
});
/*global Todos DS*/
'use strict';
Todos.Store = DS.Store.extend({
revision: 11,
adapter: 'Todos.LSAdapter'
......
/*global Todos DS Ember*/
'use strict';
Todos.Todo = DS.Model.extend({
title: DS.attr('string'),
isCompleted: DS.attr('boolean'),
todoDidChange: function() {
Ember.run.once(this, function() {
todoDidChange: function () {
Ember.run.once(this, function () {
this.get('store').commit();
});
}.observes('isCompleted', 'title')
......
Todos.Router.map(function() {
this.resource('todos', { path: '/' }, function() {
/*global Todos Ember*/
'use strict';
Todos.Router.map(function () {
this.resource('todos', { path: '/' }, function () {
this.route('active');
this.route('completed');
});
});
Todos.TodosRoute = Ember.Route.extend({
model: function() {
model: function () {
return Todos.Todo.find();
}
});
Todos.TodosIndexRoute = Ember.Route.extend({
setupController: function() {
setupController: function () {
var todos = Todos.Todo.find();
this.controllerFor('todos').set('filteredTodos', todos);
}
});
Todos.TodosActiveRoute = Ember.Route.extend({
setupController: function() {
var todos = Todos.Todo.filter(function(todo) {
setupController: function () {
var todos = Todos.Todo.filter(function (todo) {
if (!todo.get('isCompleted')) { return true; }
});
......@@ -29,8 +32,8 @@ Todos.TodosActiveRoute = Ember.Route.extend({
});
Todos.TodosCompletedRoute = Ember.Route.extend({
setupController: function() {
var todos = Todos.Todo.filter(function(todo) {
setupController: function () {
var todos = Todos.Todo.filter(function (todo) {
if (todo.get('isCompleted')) { return true; }
});
......
/*global Todos Ember*/
'use strict';
Todos.EditTodoView = Ember.TextField.extend({
classNames: ['edit'],
valueBinding: 'todo.title',
change: function() {
change: function () {
var value = this.get('value');
if (Ember.isEmpty(value)) {
......@@ -11,15 +14,15 @@ Todos.EditTodoView = Ember.TextField.extend({
}
},
focusOut: function() {
focusOut: function () {
this.set('controller.isEditing', false);
},
insertNewline: function() {
insertNewline: function () {
this.set('controller.isEditing', false);
},
didInsertElement: function() {
didInsertElement: function () {
this.$().focus();
}
});
/*global Todos Ember*/
'use strict';
Todos.TodoView = Ember.View.extend({
tagName: 'li',
classNameBindings: ['todo.isCompleted:completed', 'isEditing:editing'],
doubleClick: function(event) {
doubleClick: function () {
this.set('isEditing', true);
}
});
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