forked from tastejs/todomvc
/
TodoMVC.TodoList.Views.js
133 lines (109 loc) · 2.82 KB
/
TodoMVC.TodoList.Views.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*global TodoMVC */
'use strict';
TodoMVC.module('TodoList.Views', function (Views, App, Backbone, Marionette, $) {
// Todo List Item View
// -------------------
//
// Display an individual todo item, and respond to changes
// that are made to the item, including marking completed.
Views.ItemView = Marionette.ItemView.extend({
tagName: 'li',
template: '#template-todoItemView',
ui: {
edit: '.edit'
},
events: {
'click .destroy': 'destroy',
'dblclick label': 'onEditClick',
'keydown .edit': 'onEditKeypress',
'focusout .edit': 'onEditFocusout',
'click .toggle': 'toggle'
},
modelEvents: {
'change': 'render'
},
onRender: function () {
this.$el.removeClass('active completed');
if (this.model.get('completed')) {
this.$el.addClass('completed');
} else {
this.$el.addClass('active');
}
},
destroy: function () {
this.model.destroy();
},
toggle: function () {
this.model.toggle().save();
},
onEditClick: function () {
this.$el.addClass('editing');
this.ui.edit.focus();
this.ui.edit.val(this.ui.edit.val());
},
onEditFocusout: function () {
var todoText = this.ui.edit.val().trim();
if (todoText) {
this.model.set('title', todoText).save();
this.$el.removeClass('editing');
} else {
this.destroy();
}
},
onEditKeypress: function (e) {
var ENTER_KEY = 13, ESC_KEY = 27;
if (e.which === ENTER_KEY) {
this.onEditFocusout();
return;
}
if (e.which === ESC_KEY) {
this.$el.removeClass('editing');
}
}
});
// Item List View
// --------------
//
// Controls the rendering of the list of items, including the
// filtering of activs vs completed items for display.
Views.ListView = Backbone.Marionette.CompositeView.extend({
template: '#template-todoListCompositeView',
itemView: Views.ItemView,
itemViewContainer: '#todo-list',
ui: {
toggle: '#toggle-all'
},
events: {
'click #toggle-all': 'onToggleAllClick'
},
collectionEvents: {
'all' : 'update'
},
onRender: function () {
this.update();
},
update: function () {
function reduceCompleted(left, right) {
return left && right.get('completed');
}
var allCompleted = this.collection.reduce(reduceCompleted, true);
this.ui.toggle.prop('checked', allCompleted);
this.$el.parent().toggle(!!this.collection.length);
},
onToggleAllClick: function (e) {
var isChecked = e.currentTarget.checked;
this.collection.each(function (todo) {
todo.save({ 'completed': isChecked });
});
}
});
// Application Event Handlers
// --------------------------
//
// Handler for filtering the list of items by showing and
// hiding through the use of various CSS classes
App.vent.on('todoList:filter', function (filter) {
filter = filter || 'all';
$('#todoapp').attr('class', 'filter-' + filter);
});
});