Commit d82fcf5a authored by Pascal Hartig's avatar Pascal Hartig

Merge pull request #616 from stephenplusplus/flight-bug

(flight) bug with clearCompleted.
parents d50f6e65 cceaffa8
/*global define */ /*global define */
'use strict'; 'use strict';
define( define([
[ './data/todos',
'./data/todos', './data/stats',
'./data/stats', './ui/new_item',
'./ui/new_item', './ui/todo_list',
'./ui/todo_list', './ui/stats',
'./ui/stats', './ui/main_selector',
'./ui/main_selector', './ui/toggle_all'
'./ui/toggle_all' ], function (TodosData, StatsData, NewItemUI, TodoListUI, StatsUI, MainSelectorUI, ToggleAllUI) {
], var initialize = function () {
StatsData.attachTo(document);
TodosData.attachTo(document);
NewItemUI.attachTo('#new-todo');
MainSelectorUI.attachTo('#main');
StatsUI.attachTo('#footer');
ToggleAllUI.attachTo('#toggle-all');
TodoListUI.attachTo('#todo-list');
};
function ( return {
TodosData, initialize: initialize
StatsData, };
NewItemUI, });
TodoListUI,
StatsUI,
MainSelectorUI,
ToggleAllUI) {
var initialize = function () {
StatsData.attachTo(document);
TodosData.attachTo(document);
NewItemUI.attachTo('#new-todo');
MainSelectorUI.attachTo('#main');
StatsUI.attachTo('#footer');
ToggleAllUI.attachTo('#toggle-all');
TodoListUI.attachTo('#todo-list');
};
return {
initialize: initialize
};
}
);
/*global define */ /*global define */
'use strict'; 'use strict';
define( define([
[ 'flight/component',
'flight/component', '../store'
'../store' ], function (defineComponent, dataStore) {
], function stats() {
this.recount = function () {
var todos = dataStore.all();
var all = todos.length;
var remaining = todos.reduce(function (memo, each) {
return memo += each.completed ? 0 : 1;
}, 0);
function (defineComponent, dataStore) { this.trigger('dataStatsCounted', {
return defineComponent(stats); all: all,
remaining: remaining,
completed: all - remaining,
filter: localStorage.getItem('filter') || ''
});
};
function stats() { this.after('initialize', function () {
this.recount = function () { this.on(document, 'dataTodosLoaded', this.recount);
var todos = dataStore.all(); this.on(document, 'dataTodoAdded', this.recount);
var all = todos.length; this.on(document, 'dataTodoRemoved', this.recount);
var remaining = todos.reduce(function (memo, each) { this.on(document, 'dataTodoToggled', this.recount);
return memo += each.completed ? 0 : 1; this.on(document, 'dataClearedCompleted', this.recount);
}, 0); this.on(document, 'dataTodoToggledAll', this.recount);
});
}
this.trigger('dataStatsCounted', { return defineComponent(stats);
all: all, });
remaining: remaining,
completed: all - remaining,
filter: localStorage.getItem('filter') || ''
});
};
this.after('initialize', function () {
this.on(document, 'dataTodosLoaded', this.recount);
this.on(document, 'dataTodoAdded', this.recount);
this.on(document, 'dataTodoRemoved', this.recount);
this.on(document, 'dataTodoToggled', this.recount);
this.on(document, 'dataClearedCompleted', this.recount);
this.on(document, 'dataTodoToggledAll', this.recount);
});
}
}
);
/*global define */ /*global define */
'use strict'; 'use strict';
define( define([
[ 'flight/component',
'flight/component', '../store'
'../store' ], function (defineComponent, dataStore) {
], function todos() {
var filter;
function (defineComponent, dataStore) {
return defineComponent(todos); this.add = function (e, data) {
var todo = dataStore.save({
function todos() { title: data.title,
var filter; completed: false
});
this.add = function (e, data) {
var todo = dataStore.save({
title: data.title,
completed: false
});
this.trigger('dataTodoAdded', { todo: todo, filter: filter });
};
this.remove = function (e, data) {
var todo = dataStore.destroy(data.id);
this.trigger('dataTodoRemoved', todo);
};
this.load = function (e, data) { this.trigger('dataTodoAdded', { todo: todo, filter: filter });
var todos; };
filter = localStorage.getItem('filter'); this.remove = function (e, data) {
todos = this.find(); var todo = dataStore.destroy(data.id);
this.trigger('dataTodosLoaded', { todos: todos });
};
this.update = function (e, data) { this.trigger('dataTodoRemoved', todo);
dataStore.save(data); };
};
this.toggleCompleted = function (e, data) { this.load = function () {
var eventType; var todos;
var todo = dataStore.get(data.id);
todo.completed = !todo.completed; filter = localStorage.getItem('filter');
dataStore.save(todo); todos = this.find();
this.trigger('dataTodosLoaded', { todos: todos });
};
eventType = filter ? 'dataTodoRemoved' : 'dataTodoToggled'; this.update = function (e, data) {
dataStore.save(data);
};
this.trigger(eventType, todo); this.toggleCompleted = function (e, data) {
}; var eventType;
var todo = dataStore.get(data.id);
this.toggleAllCompleted = function (e, data) { todo.completed = !todo.completed;
dataStore.updateAll({ completed: data.completed }); dataStore.save(todo);
this.trigger('dataTodoToggledAll', { todos: this.find(filter) });
};
this.filter = function (e, data) { eventType = filter ? 'dataTodoRemoved' : 'dataTodoToggled';
var todos;
localStorage.setItem('filter', data.filter); this.trigger(eventType, todo);
filter = data.filter; };
todos = this.find();
this.trigger('dataTodosFiltered', { todos: todos }); this.toggleAllCompleted = function (e, data) {
}; dataStore.updateAll({ completed: data.completed });
this.trigger('dataTodoToggledAll', { todos: this.find(filter) });
};
this.find = function () { this.filter = function (e, data) {
var todos; var todos;
if (filter) { localStorage.setItem('filter', data.filter);
todos = dataStore.find(function (each) { filter = data.filter;
return (typeof each[filter] !== 'undefined') ? each.completed : !each.completed; todos = this.find();
});
}
else {
todos = dataStore.all();
}
return todos; this.trigger('dataTodosFiltered', { todos: todos });
}; };
this.clearCompleted = function () { this.find = function () {
var todos; var todos;
dataStore.destroyAll({ completed: true }); if (filter) {
todos = dataStore.find(function (each) {
return (typeof each[filter] !== 'undefined') ? each.completed : !each.completed;
});
} else {
todos = dataStore.all(); todos = dataStore.all();
this.trigger('dataClearedCompleted', { todos: todos }); }
};
return todos;
this.after('initialize', function () { };
this.on(document, 'uiAddRequested', this.add);
this.on(document, 'uiUpdateRequested', this.update); this.clearCompleted = function () {
this.on(document, 'uiRemoveRequested', this.remove); dataStore.destroyAll({ completed: true });
this.on(document, 'uiLoadRequested', this.load);
this.on(document, 'uiToggleRequested', this.toggleCompleted); this.trigger('uiFilterRequested', { filter: filter });
this.on(document, 'uiToggleAllRequested', this.toggleAllCompleted); this.trigger('dataClearedCompleted');
this.on(document, 'uiClearRequested', this.clearCompleted); };
this.on(document, 'uiFilterRequested', this.filter);
}); this.after('initialize', function () {
} this.on(document, 'uiAddRequested', this.add);
this.on(document, 'uiUpdateRequested', this.update);
this.on(document, 'uiRemoveRequested', this.remove);
this.on(document, 'uiLoadRequested', this.load);
this.on(document, 'uiToggleRequested', this.toggleCompleted);
this.on(document, 'uiToggleAllRequested', this.toggleAllCompleted);
this.on(document, 'uiClearRequested', this.clearCompleted);
this.on(document, 'uiFilterRequested', this.filter);
});
} }
);
return defineComponent(todos);
});
'use strict'; /*global define */
define( 'use strict';
[
'depot'
],
function (depot) { define([
return depot('todos', { idAttribute: 'id' }); 'depot'
} ], function (depot) {
); return depot('todos', { idAttribute: 'id' });
});
/*global define */ /*global define */
'use strict'; 'use strict';
define( define([
[ 'flight/component'
'flight/component' ], function (defineComponent) {
], function mainSelector() {
this.toggle = function (e, data) {
var toggle = data.all > 0;
this.$node.toggle(toggle);
};
function (defineComponent) { this.after('initialize', function () {
return defineComponent(mainSelector); this.$node.hide();
this.on(document, 'dataStatsCounted', this.toggle);
function mainSelector() { });
this.toggle = function (e, data) {
var toggle = data.all > 0;
this.$node.toggle(toggle);
};
this.after('initialize', function () {
this.$node.hide();
this.on(document, 'dataStatsCounted', this.toggle);
});
}
} }
);
return defineComponent(mainSelector);
});
/*global define */ /*global define */
'use strict'; 'use strict';
define( define([
[ 'flight/component'
'flight/component' ], function (defineComponent) {
], function newItem() {
var ENTER_KEY = 13;
function (defineComponent) { this.createOnEnter = function (e) {
return defineComponent(newItem); if (e.which !== ENTER_KEY ||
!this.$node.val().trim()) {
return;
}
function newItem() { this.trigger('uiAddRequested', {
var ENTER_KEY = 13; title: this.$node.val().trim()
});
this.createOnEnter = function (e) {
if (e.which !== ENTER_KEY ||
!this.$node.val().trim()) {
return;
}
this.trigger('uiAddRequested', {
title: this.$node.val().trim()
});
this.$node.val(''); this.$node.val('');
}; };
this.after('initialize', function () { this.after('initialize', function () {
this.on('keydown', this.createOnEnter); this.on('keydown', this.createOnEnter);
}); });
}
} }
);
return defineComponent(newItem);
});
/*global define */ /*global define */
'use strict'; 'use strict';
define( define([
[ 'flight/component',
'flight/component', './with_filters',
'./with_filters', 'text!app/templates/stats.html',
'text!app/templates/stats.html', '../utils'
'../utils' ], function (defineComponent, withFilters, statsTmpl, utils) {
], function stats() {
var template = utils.tmpl(statsTmpl);
function (defineComponent, withFilters, statsTmpl, utils) {
return defineComponent(stats, withFilters); this.defaultAttrs({
clearCompletedSelector: '#clear-completed'
function stats() { });
var template = utils.tmpl(statsTmpl);
this.render = function (e, data) {
this.defaultAttrs({ var toggle = data.all > 0;
clearCompletedSelector: '#clear-completed'
}); this.$node.html(template(data));
this.$node.toggle(toggle);
this.render = function (e, data) { this.markSelected(data.filter);
var toggle = data.all > 0; };
this.$node.html(template(data)); this.clearCompleted = function () {
this.$node.toggle(toggle); this.trigger('uiClearRequested');
this.markSelected(data.filter); };
};
this.after('initialize', function () {
this.clearCompleted = function (e, data) { this.$node.hide();
this.trigger('uiClearRequested'); this.on(document, 'dataStatsCounted', this.render);
}; this.on('click', { 'clearCompletedSelector': this.clearCompleted });
});
this.after('initialize', function () {
this.$node.hide();
this.on(document, 'dataStatsCounted', this.render);
this.on('click', { 'clearCompletedSelector': this.clearCompleted });
});
}
} }
);
return defineComponent(stats, withFilters);
});
/*global define $ */ /*global define, $ */
'use strict'; 'use strict';
define( define([
[ 'flight/component',
'flight/component', 'text!app/templates/todo.html',
'text!app/templates/todo.html', '../utils'
'../utils' ], function (defineComponent, todoTmpl, utils) {
], function todoList() {
var ENTER_KEY = 13;
function (defineComponent, todoTmpl, utils) { var template = utils.tmpl(todoTmpl);
return defineComponent(todoList);
this.defaultAttrs({
function todoList() { destroySelector: 'button.destroy',
var ENTER_KEY = 13; toggleSelector: 'input.toggle',
var template = utils.tmpl(todoTmpl); labelSelector: 'label',
editSelector: '.edit'
this.defaultAttrs({ });
destroySelector: 'button.destroy',
toggleSelector: 'input.toggle', this.renderAll = function (e, data) {
labelSelector: 'label', this.$node.html('');
editSelector: '.edit' data.todos.forEach(function (each) {
}); this.render(e, { todo: each });
}, this);
this.renderAll = function (e, data) { };
this.$node.html('');
data.todos.forEach(function (each) { this.render = function (e, data) {
this.render(e, { todo: each }); if (e.type === 'dataTodoAdded' && data.filter === 'completed') {
}, this); return;
}; }
this.render = function (e, data) { this.$node.append(template(data.todo));
if (e.type === 'dataTodoAdded' && data.filter === 'completed') { };
return;
} this.edit = function (e, data) {
var $todoEl = $(data.el).parents('li');
this.$node.append(template(data.todo));
}; $todoEl.addClass('editing');
this.select('editSelector').focus();
this.edit = function (e, data) { };
var $todoEl = $(data.el).parents('li');
this.requestUpdate = function (e) {
$todoEl.addClass('editing'); var $inputEl = $(e.currentTarget);
this.select('editSelector').focus(); var $todoEl = $inputEl.parents('li');
}; var value = $inputEl.val().trim();
var id = $todoEl.attr('id');
this.requestUpdate = function (e, data) {
var $inputEl = $(e.currentTarget); if (!$todoEl.hasClass('editing')) {
var $todoEl = $inputEl.parents('li'); return;
var value = $inputEl.val().trim(); }
var id = $todoEl.attr('id');
$todoEl.removeClass('editing');
if (!$todoEl.hasClass('editing')) {
return; if (value) {
} $todoEl.find('label').html(value);
this.trigger('uiUpdateRequested', { id: id, title: value });
!$todoEl.removeClass('editing'); } else {
if (value) {
$todoEl.find('label').html(value);
this.trigger('uiUpdateRequested', { id: id, title: value });
} else {
this.trigger('uiRemoveRequested', { id: id });
}
};
this.requestUpdateOnEnter = function (e, data) {
if (e.which === ENTER_KEY) {
this.requestUpdate(e, data);
}
};
this.requestRemove = function (e, data) {
var id = $(data.el).attr('id').split('_')[1];
this.trigger('uiRemoveRequested', { id: id }); this.trigger('uiRemoveRequested', { id: id });
}; }
};
this.remove = function (e, data) {
var $todoEl = this.$node.find('#' + data.id); this.requestUpdateOnEnter = function (e, data) {
$todoEl.remove(); if (e.which === ENTER_KEY) {
}; this.requestUpdate(e, data);
}
this.toggle = function (e, data) { };
var $todoEl = $(data.el).parents('li');
this.requestRemove = function (e, data) {
$todoEl.toggleClass('completed'); var id = $(data.el).attr('id').split('_')[1];
this.trigger('uiToggleRequested', { id: $todoEl.attr('id') }); this.trigger('uiRemoveRequested', { id: id });
}; };
this.after('initialize', function () { this.remove = function (e, data) {
this.on(document, 'dataTodoAdded', this.render); var $todoEl = this.$node.find('#' + data.id);
this.on(document, 'dataTodosLoaded', this.renderAll); $todoEl.remove();
this.on(document, 'dataTodosFiltered', this.renderAll); };
this.on(document, 'dataClearedCompleted', this.renderAll);
this.on(document, 'dataTodoToggledAll', this.renderAll); this.toggle = function (e, data) {
this.on(document, 'dataTodoRemoved', this.remove); var $todoEl = $(data.el).parents('li');
this.on('click', { 'destroySelector': this.requestRemove }); $todoEl.toggleClass('completed');
this.on('click', { 'toggleSelector': this.toggle }); this.trigger('uiToggleRequested', { id: $todoEl.attr('id') });
this.on('dblclick', { 'labelSelector': this.edit }); };
this.$node.on('blur', '.edit', this.bind(this.requestUpdate)); this.after('initialize', function () {
this.$node.on('keydown', '.edit', this.bind(this.requestUpdateOnEnter)); this.on(document, 'dataTodoAdded', this.render);
this.on(document, 'dataTodosLoaded', this.renderAll);
// these don't work this.on(document, 'dataTodosFiltered', this.renderAll);
// this.on(this.attr.editSelector, 'blur', this.requestUpdate); this.on(document, 'dataTodoToggledAll', this.renderAll);
// this.on('blur', { 'editSelector': this.requestUpdate }); this.on(document, 'dataTodoRemoved', this.remove);
this.trigger('uiLoadRequested'); this.on('click', { 'destroySelector': this.requestRemove });
}); this.on('click', { 'toggleSelector': this.toggle });
} this.on('dblclick', { 'labelSelector': this.edit });
this.$node.on('blur', '.edit', this.bind(this.requestUpdate));
this.$node.on('keydown', '.edit', this.bind(this.requestUpdateOnEnter));
// these don't work
// this.on(this.attr.editSelector, 'blur', this.requestUpdate);
// this.on('blur', { 'editSelector': this.requestUpdate });
this.trigger('uiLoadRequested');
});
} }
);
return defineComponent(todoList);
});
/*global define */ /*global define */
'use strict'; 'use strict';
define( define([
[ 'flight/component'
'flight/component' ], function (defineComponent) {
], function toggleAll() {
this.toggleAllComplete = function () {
function (defineComponent) { this.trigger('uiToggleAllRequested', {
return defineComponent(toggleAll); completed: this.$node.is(':checked')
});
function toggleAll() { };
this.toggleAllComplete = function () {
this.trigger('uiToggleAllRequested', {
completed: this.$node.is(':checked')
});
};
this.toggleCheckbox = function (e, data) { this.toggleCheckbox = function (e, data) {
this.$node[0].checked = !data.remaining; this.$node[0].checked = !data.remaining;
}; };
this.after('initialize', function () { this.after('initialize', function () {
this.on('click', this.toggleAllComplete); this.on('click', this.toggleAllComplete);
this.on(document, 'dataStatsCounted', this.toggleCheckbox); this.on(document, 'dataStatsCounted', this.toggleCheckbox);
}); });
}
} }
);
return defineComponent(toggleAll);
});
/*global define $ */ /*global define, $ */
'use strict'; 'use strict';
define( define(function () {
function () { return function withFilters() {
return function withFilters() { this.defaultAttrs({
this.defaultAttrs({ filterSelector: '#filters a'
filterSelector: '#filters a' });
});
this.chooseFilter = function (e, data) { this.chooseFilter = function (e, data) {
var filter = data.el.hash.slice(2); var filter = data.el.hash.slice(2);
this.select('filterSelector').removeClass('selected'); this.select('filterSelector').removeClass('selected');
$(data.el).addClass('selected'); $(data.el).addClass('selected');
this.trigger('uiFilterRequested', { filter: filter }); this.trigger('uiFilterRequested', { filter: filter });
}; };
this.markSelected = function (filter) {
this.$node.find('[href="#/' + filter + '"]').addClass('selected');
};
this.after('initialize', function () { this.markSelected = function (filter) {
this.on('click', { filterSelector: this.chooseFilter }); this.$node.find('[href="#/' + filter + '"]').addClass('selected');
});
}; };
}
); this.after('initialize', function () {
this.on('click', { filterSelector: this.chooseFilter });
});
};
});
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
// tmpl function scooped from underscore. // tmpl function scooped from underscore.
// http://documentcloud.github.com/underscore/#template // http://documentcloud.github.com/underscore/#template
define(function () { define(function () {
var _ = {}; var _ = {};
// List of HTML entities for escaping. // List of HTML entities for escaping.
...@@ -128,5 +127,7 @@ define(function () { ...@@ -128,5 +127,7 @@ define(function () {
return template; return template;
}; };
return { tmpl: template }; return {
tmpl: template
};
}); });
<span id="todo-count"><strong><%= remaining %></strong> <%= remaining == 1 ? 'item' : 'items' %> left</span> <span id="todo-count">
<strong><%= remaining %></strong> <%= remaining == 1 ? 'item' : 'items' %> left
</span>
<ul id="filters"> <ul id="filters">
<li> <li>
<a href="#/">All</a> <a href="#/">All</a>
...@@ -11,5 +13,5 @@ ...@@ -11,5 +13,5 @@
</li> </li>
</ul> </ul>
<% if (completed) { %> <% if (completed) { %>
<button id="clear-completed">Clear completed (<%= completed %>)</button> <button id="clear-completed">Clear completed (<%= completed %>)</button>
<% } %> <% } %>
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