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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182 | 1
1
1
24
1
41
27
27
27
27
41
17
17
12
12
12
1
67
67
1
128
108
108
108
43
35
35
35
36
18
12
24
12
9
3
6
1
172
1
260
141
141
141
135
92
43
43
43
41
1
173
173
173
173
69
69
104
33
33
71
71
71
1
| Backbone.Picky = (function (Backbone, _) {
var Picky = {};
// Picky.SingleSelect
// ------------------
// A single-select mixin for Backbone.Collection, allowing a single
// model to be selected within a collection. Selection of another
// model within the collection causes the previous model to be
// deselected.
Picky.SingleSelect = function(collection){
this.collection = collection;
};
_.extend(Picky.SingleSelect.prototype, {
// Select a model, deselecting any previously
// selected model
select: function(model){
if (model && this.selected === model) { return; }
this.deselect();
this.selected = model;
this.selected.select();
this.trigger("select:one", model);
},
// Deselect a model, resulting in no model
// being selected
deselect: function(model){
if (!this.selected){ return; }
model = model || this.selected;
if (this.selected !== model){ return; }
this.selected.deselect();
this.trigger("deselect:one", this.selected);
delete this.selected;
}
});
// Picky.MultiSelect
// -----------------
// A mult-select mixin for Backbone.Collection, allowing a collection to
// have multiple items selected, including `selectAll` and `selectNone`
// capabilities.
Picky.MultiSelect = function (collection) {
this.collection = collection;
this.selected = {};
};
_.extend(Picky.MultiSelect.prototype, {
// Select a specified model, make sure the
// model knows it's selected, and hold on to
// the selected model.
select: function (model) {
if (this.selected[model.cid]) { return; }
this.selected[model.cid] = model;
model.select();
calculateSelectedLength(this);
},
// Deselect a specified model, make sure the
// model knows it has been deselected, and remove
// the model from the selected list.
deselect: function (model) {
if (!this.selected[model.cid]) { return; }
delete this.selected[model.cid];
model.deselect();
calculateSelectedLength(this);
},
// Select all models in this collection
selectAll: function () {
this.each(function (model) { model.select(); });
calculateSelectedLength(this);
},
// Deselect all models in this collection
selectNone: function () {
Iif (this.selectedLength === 0) { return; }
this.each(function (model) { model.deselect(); });
calculateSelectedLength(this);
},
// Toggle select all / none. If some are selected, it
// will select all. If all are selected, it will select
// none. If none are selected, it will select all.
toggleSelectAll: function () {
if (this.selectedLength === this.length) {
this.selectNone();
} else {
this.selectAll();
}
}
});
// Picky.Selectable
// ----------------
// A selectable mixin for Backbone.Model, allowing a model to be selected,
// enabling it to work with Picky.MultiSelect or on it's own
Picky.Selectable = function (model) {
this.model = model;
};
_.extend(Picky.Selectable.prototype, {
// Select this model, and tell our
// collection that we're selected
select: function () {
if (this.selected) { return; }
this.selected = true;
this.trigger("selected", this);
if (this.collection) {
this.collection.select(this);
}
},
// Deselect this model, and tell our
// collection that we're deselected
deselect: function () {
if (!this.selected) { return; }
this.selected = false;
this.trigger("deselected", this);
if (this.collection) {
this.collection.deselect(this);
}
},
// Change selected to the opposite of what
// it currently is
toggleSelected: function () {
if (this.selected) {
this.deselect();
} else {
this.select();
}
}
});
// Helper Methods
// --------------
// Calculate the number of selected items in a collection
// and update the collection with that length. Trigger events
// from the collection based on the number of selected items.
var calculateSelectedLength = function (collection) {
collection.selectedLength = _.size(collection.selected);
var selectedLength = collection.selectedLength;
var length = collection.length;
if (selectedLength === length) {
collection.trigger("select:all", collection);
return;
}
if (selectedLength === 0) {
collection.trigger("select:none", collection);
return;
}
Eif (selectedLength > 0 && selectedLength < length) {
collection.trigger("select:some", collection);
return;
}
};
return Picky;
})(Backbone, _);
|