Diffstat (limited to 'frontend/beta/js/YUI-extensions/grid/SelectionModel.js') (more/less context) (ignore whitespace changes)
-rw-r--r-- | frontend/beta/js/YUI-extensions/grid/SelectionModel.js | 445 |
1 files changed, 445 insertions, 0 deletions
diff --git a/frontend/beta/js/YUI-extensions/grid/SelectionModel.js b/frontend/beta/js/YUI-extensions/grid/SelectionModel.js new file mode 100644 index 0000000..6981440 --- a/dev/null +++ b/frontend/beta/js/YUI-extensions/grid/SelectionModel.js | |||
@@ -0,0 +1,445 @@ | |||
1 | /** | ||
2 | @class YAHOO.ext.grid.DefaultSelectionModel | ||
3 | * @extends YAHOO.ext.util.Observable | ||
4 | * The default SelectionModel used by {@link YAHOO.ext.grid.Grid}. | ||
5 | It supports multiple selections and keyboard selection/navigation. <br><br> | ||
6 | @constructor | ||
7 | */ | ||
8 | YAHOO.ext.grid.DefaultSelectionModel = function(){ | ||
9 | this.selectedRows = []; | ||
10 | this.selectedRowIds = []; | ||
11 | this.lastSelectedRow = null; | ||
12 | |||
13 | this.onRowSelect = new YAHOO.util.CustomEvent('SelectionTable.rowSelected'); | ||
14 | this.onSelectionChange = new YAHOO.util.CustomEvent('SelectionTable.selectionChanged'); | ||
15 | |||
16 | this.events = { | ||
17 | /** | ||
18 | * @event selectionchange | ||
19 | * Fires when the selection changes | ||
20 | * @param {SelectionModel} this | ||
21 | * @param {Array} rows Array of row elements that are selected | ||
22 | * @param {String} ids Array of ids that are selected | ||
23 | */ | ||
24 | 'selectionchange' : this.onSelectionChange, | ||
25 | /** | ||
26 | * @event rowselect | ||
27 | * Fires when a row is selected or deselected | ||
28 | * @param {SelectionModel} this | ||
29 | * @param {HTMLElement} row The row element | ||
30 | * @param {Boolean} selected true if the row was selected, false if deselected | ||
31 | */ | ||
32 | 'rowselect' : this.onRowSelect | ||
33 | }; | ||
34 | |||
35 | this.locked = false; | ||
36 | }; | ||
37 | |||
38 | YAHOO.ext.grid.DefaultSelectionModel.prototype = { | ||
39 | /** @ignore Called by the grid automatically. Do not call directly. */ | ||
40 | init : function(grid){ | ||
41 | this.grid = grid; | ||
42 | this.initEvents(); | ||
43 | }, | ||
44 | |||
45 | /** | ||
46 | * Lock the selections | ||
47 | */ | ||
48 | lock : function(){ | ||
49 | this.locked = true; | ||
50 | }, | ||
51 | |||
52 | /** | ||
53 | * Unlock the selections | ||
54 | */ | ||
55 | unlock : function(){ | ||
56 | this.locked = false; | ||
57 | }, | ||
58 | |||
59 | /** | ||
60 | * Returns true if the selections are locked | ||
61 | * @return {Boolean} | ||
62 | */ | ||
63 | isLocked : function(){ | ||
64 | return this.locked; | ||
65 | }, | ||
66 | |||
67 | /** @ignore */ | ||
68 | initEvents : function(){ | ||
69 | if(this.grid.trackMouseOver){ | ||
70 | this.grid.addListener("mouseover", this.handleOver, this, true); | ||
71 | this.grid.addListener("mouseout", this.handleOut, this, true); | ||
72 | } | ||
73 | this.grid.addListener("rowclick", this.rowClick, this, true); | ||
74 | this.grid.addListener("keydown", this.keyDown, this, true); | ||
75 | }, | ||
76 | |||
77 | fireEvent : YAHOO.ext.util.Observable.prototype.fireEvent, | ||
78 | on : YAHOO.ext.util.Observable.prototype.on, | ||
79 | addListener : YAHOO.ext.util.Observable.prototype.addListener, | ||
80 | delayedListener : YAHOO.ext.util.Observable.prototype.delayedListener, | ||
81 | removeListener : YAHOO.ext.util.Observable.prototype.removeListener, | ||
82 | purgeListeners : YAHOO.ext.util.Observable.prototype.purgeListeners, | ||
83 | bufferedListener : YAHOO.ext.util.Observable.prototype.bufferedListener, | ||
84 | |||
85 | /** @ignore Syncs selectedRows with the correct row by looking it up by id. | ||
86 | Used after a sort moves data around. */ | ||
87 | syncSelectionsToIds : function(){ | ||
88 | if(this.getCount() > 0){ | ||
89 | var ids = this.selectedRowIds.concat(); | ||
90 | this.clearSelections(); | ||
91 | this.selectRowsById(ids, true); | ||
92 | } | ||
93 | }, | ||
94 | |||
95 | /** | ||
96 | * Set the selected rows by their ID(s). IDs must match what is returned by the DataModel getRowId(index). | ||
97 | * @param {String/Array} id The id(s) to select | ||
98 | * @param {<i>Boolean</i>} keepExisting (optional) True to retain existing selections | ||
99 | */ | ||
100 | selectRowsById : function(id, keepExisting){ | ||
101 | var rows = this.grid.getRowsById(id); | ||
102 | if (!(rows instanceof Array)){ | ||
103 | this.selectRow(rows, keepExisting); | ||
104 | return; | ||
105 | } | ||
106 | this.selectRows(rows, keepExisting); | ||
107 | }, | ||
108 | |||
109 | /** | ||
110 | * Gets the number of selected rows. | ||
111 | * @return {Number} | ||
112 | */ | ||
113 | getCount : function(){ | ||
114 | return this.selectedRows.length; | ||
115 | }, | ||
116 | |||
117 | /** | ||
118 | * Selects the first row in the grid. | ||
119 | */ | ||
120 | selectFirstRow : function(){ | ||
121 | for(var j = 0; j < this.grid.rows.length; j++){ | ||
122 | if(this.isSelectable(this.grid.rows[j])){ | ||
123 | this.focusRow(this.grid.rows[j]); | ||
124 | this.setRowState(this.grid.rows[j], true); | ||
125 | return; | ||
126 | } | ||
127 | } | ||
128 | }, | ||
129 | |||
130 | /** | ||
131 | * Selects the row immediately following the last selected row. | ||
132 | * @param {<i>Boolean</i>} keepExisting (optional) True to retain existing selections | ||
133 | */ | ||
134 | selectNext : function(keepExisting){ | ||
135 | if(this.lastSelectedRow){ | ||
136 | for(var j = (this.lastSelectedRow.rowIndex+1); j < this.grid.rows.length; j++){ | ||
137 | var row = this.grid.rows[j]; | ||
138 | if(this.isSelectable(row)){ | ||
139 | this.focusRow(row); | ||
140 | this.setRowState(row, true, keepExisting); | ||
141 | return; | ||
142 | } | ||
143 | } | ||
144 | } | ||
145 | }, | ||
146 | |||
147 | /** | ||
148 | * Selects the row that precedes the last selected row. | ||
149 | * @param {<i>Boolean</i>} keepExisting (optional) True to retain existing selections | ||
150 | */ | ||
151 | selectPrevious : function(keepExisting){ | ||
152 | if(this.lastSelectedRow){ | ||
153 | for(var j = (this.lastSelectedRow.rowIndex-1); j >= 0; j--){ | ||
154 | var row = this.grid.rows[j]; | ||
155 | if(this.isSelectable(row)){ | ||
156 | this.focusRow(row); | ||
157 | this.setRowState(row, true, keepExisting); | ||
158 | return; | ||
159 | } | ||
160 | } | ||
161 | } | ||
162 | }, | ||
163 | |||
164 | /** | ||
165 | * Returns the selected rows. | ||
166 | * @return {Array} Array of DOM row elements | ||
167 | */ | ||
168 | getSelectedRows : function(){ | ||
169 | return this.selectedRows; | ||
170 | }, | ||
171 | |||
172 | /** | ||
173 | * Returns the selected row ids. | ||
174 | * @return {Array} Array of String ids | ||
175 | */ | ||
176 | getSelectedRowIds : function(){ | ||
177 | return this.selectedRowIds; | ||
178 | }, | ||
179 | |||
180 | /** | ||
181 | * Clears all selections. | ||
182 | */ | ||
183 | clearSelections : function(){ | ||
184 | if(this.isLocked()) return; | ||
185 | var oldSelections = this.selectedRows.concat(); | ||
186 | for(var j = 0; j < oldSelections.length; j++){ | ||
187 | this.setRowState(oldSelections[j], false); | ||
188 | } | ||
189 | this.selectedRows = []; | ||
190 | this.selectedRowIds = []; | ||
191 | }, | ||
192 | |||
193 | |||
194 | /** | ||
195 | * Selects all rows. | ||
196 | */ | ||
197 | selectAll : function(){ | ||
198 | if(this.isLocked()) return; | ||
199 | this.selectedRows = []; | ||
200 | this.selectedRowIds = []; | ||
201 | for(var j = 0, len = this.grid.rows.length; j < len; j++){ | ||
202 | this.setRowState(this.grid.rows[j], true, true); | ||
203 | } | ||
204 | }, | ||
205 | |||
206 | /** | ||
207 | * Returns True if there is a selection. | ||
208 | * @return {Boolean} | ||
209 | */ | ||
210 | hasSelection : function(){ | ||
211 | return this.selectedRows.length > 0; | ||
212 | }, | ||
213 | |||
214 | /** | ||
215 | * Returns True if the specified row is selected. | ||
216 | * @param {HTMLElement} row The row to check | ||
217 | * @return {Boolean} | ||
218 | */ | ||
219 | isSelected : function(row){ | ||
220 | return row && (row.selected === true || row.getAttribute('selected') == 'true'); | ||
221 | }, | ||
222 | |||
223 | /** | ||
224 | * Returns True if the specified row is selectable. | ||
225 | * @param {HTMLElement} row The row to check | ||
226 | * @return {Boolean} | ||
227 | */ | ||
228 | isSelectable : function(row){ | ||
229 | return row && row.getAttribute('selectable') != 'false'; | ||
230 | }, | ||
231 | |||
232 | /** @ignore */ | ||
233 | rowClick : function(grid, rowIndex, e){ | ||
234 | if(this.isLocked()) return; | ||
235 | var row = grid.getRow(rowIndex); | ||
236 | if(this.isSelectable(row)){ | ||
237 | if(e.shiftKey && this.lastSelectedRow){ | ||
238 | var lastIndex = this.lastSelectedRow.rowIndex; | ||
239 | this.selectRange(this.lastSelectedRow, row, e.ctrlKey); | ||
240 | this.lastSelectedRow = this.grid.el.dom.rows[lastIndex]; | ||
241 | }else{ | ||
242 | this.focusRow(row); | ||
243 | var rowState = e.ctrlKey ? !this.isSelected(row) : true; | ||
244 | this.setRowState(row, rowState, e.hasModifier()); | ||
245 | } | ||
246 | } | ||
247 | }, | ||
248 | |||
249 | /** | ||
250 | * Deprecated. Tries to focus the row and scroll it into view - Use grid.scrollTo or grid.getView().focusRow() instead. | ||
251 | * @deprecated | ||
252 | * @param {HTMLElement} row The row to focus | ||
253 | */ | ||
254 | focusRow : function(row){ | ||
255 | this.grid.view.focusRow(row); | ||
256 | }, | ||
257 | |||
258 | /** | ||
259 | * Selects a row. | ||
260 | * @param {Number/HTMLElement} row The row or index of the row to select | ||
261 | * @param {<i>Boolean</i>} keepExisting (optional) True to retain existing selections | ||
262 | */ | ||
263 | selectRow : function(row, keepExisting){ | ||
264 | this.setRowState(this.getRow(row), true, keepExisting); | ||
265 | }, | ||
266 | |||
267 | /** | ||
268 | * Selects multiple rows. | ||
269 | * @param {Array} rows Array of the rows or indexes of the row to select | ||
270 | * @param {<i>Boolean</i>} keepExisting (optional) True to retain existing selections | ||
271 | */ | ||
272 | selectRows : function(rows, keepExisting){ | ||
273 | if(!keepExisting){ | ||
274 | this.clearSelections(); | ||
275 | } | ||
276 | for(var i = 0; i < rows.length; i++){ | ||
277 | this.selectRow(rows[i], true); | ||
278 | } | ||
279 | }, | ||
280 | |||
281 | /** | ||
282 | * Deselects a row. | ||
283 | * @param {Number/HTMLElement} row The row or index of the row to deselect | ||
284 | */ | ||
285 | deselectRow : function(row){ | ||
286 | this.setRowState(this.getRow(row), false); | ||
287 | }, | ||
288 | |||
289 | /** @ignore */ | ||
290 | getRow : function(row){ | ||
291 | if(typeof row == 'number'){ | ||
292 | row = this.grid.rows[row]; | ||
293 | } | ||
294 | return row; | ||
295 | }, | ||
296 | |||
297 | /** | ||
298 | * Selects a range of rows. All rows in between startRow and endRow are also selected. | ||
299 | * @param {Number/HTMLElement} startRow The row or index of the first row in the range | ||
300 | * @param {Number/HTMLElement} endRow The row or index of the last row in the range | ||
301 | * @param {<i>Boolean</i>} keepExisting (optional) True to retain existing selections | ||
302 | */ | ||
303 | selectRange : function(startRow, endRow, keepExisting){ | ||
304 | startRow = this.getRow(startRow); | ||
305 | endRow = this.getRow(endRow); | ||
306 | this.setRangeState(startRow, endRow, true, keepExisting); | ||
307 | }, | ||
308 | |||
309 | /** | ||
310 | * Deselects a range of rows. All rows in between startRow and endRow are also deselected. | ||
311 | * @param {Number/HTMLElement} startRow The row or index of the first row in the range | ||
312 | * @param {Number/HTMLElement} endRow The row or index of the last row in the range | ||
313 | */ | ||
314 | deselectRange : function(startRow, endRow){ | ||
315 | startRow = this.getRow(startRow); | ||
316 | endRow = this.getRow(endRow); | ||
317 | this.setRangeState(startRow, endRow, false, true); | ||
318 | }, | ||
319 | |||
320 | /** @ignore */ | ||
321 | setRowStateFromChild : function(childEl, selected, keepExisting){ | ||
322 | var row = this.grid.getRowFromChild(childEl); | ||
323 | this.setRowState(row, selected, keepExisting); | ||
324 | }, | ||
325 | |||
326 | /** @ignore */ | ||
327 | setRangeState : function(startRow, endRow, selected, keepExisting){ | ||
328 | if(this.isLocked()) return; | ||
329 | if(!keepExisting){ | ||
330 | this.clearSelections(); | ||
331 | } | ||
332 | var curRow = startRow; | ||
333 | while(curRow.rowIndex != endRow.rowIndex){ | ||
334 | this.setRowState(curRow, selected, true); | ||
335 | curRow = (startRow.rowIndex < endRow.rowIndex ? | ||
336 | this.grid.getRowAfter(curRow) : this.grid.getRowBefore(curRow)) | ||
337 | } | ||
338 | this.setRowState(endRow, selected, true); | ||
339 | }, | ||
340 | |||
341 | /** @ignore */ | ||
342 | setRowState : function(row, selected, keepExisting){ | ||
343 | if(this.isLocked()) return; | ||
344 | if(this.isSelectable(row)){ | ||
345 | if(selected){ | ||
346 | if(!keepExisting){ | ||
347 | this.clearSelections(); | ||
348 | } | ||
349 | this.setRowClass(row, 'selected'); | ||
350 | row.selected = true; | ||
351 | this.selectedRows.push(row); | ||
352 | this.selectedRowIds.push(this.grid.dataModel.getRowId(row.rowIndex)); | ||
353 | this.lastSelectedRow = row; | ||
354 | }else{ | ||
355 | this.setRowClass(row, ''); | ||
356 | row.selected = false; | ||
357 | this._removeSelected(row); | ||
358 | } | ||
359 | this.fireEvent('rowselect', this, row, selected); | ||
360 | this.fireEvent('selectionchange', this, this.selectedRows, this.selectedRowIds); | ||
361 | } | ||
362 | }, | ||
363 | |||
364 | /** @ignore */ | ||
365 | handleOver : function(e){ | ||
366 | var row = this.grid.getRowFromChild(e.getTarget()); | ||
367 | if(this.isSelectable(row) && !this.isSelected(row)){ | ||
368 | this.setRowClass(row, 'over'); | ||
369 | } | ||
370 | }, | ||
371 | |||
372 | /** @ignore */ | ||
373 | handleOut : function(e){ | ||
374 | var row = this.grid.getRowFromChild(e.getTarget()); | ||
375 | if(this.isSelectable(row) && !this.isSelected(row)){ | ||
376 | this.setRowClass(row, ''); | ||
377 | } | ||
378 | }, | ||
379 | |||
380 | /** @ignore */ | ||
381 | keyDown : function(e){ | ||
382 | if(e.browserEvent.keyCode == e.DOWN){ | ||
383 | this.selectNext(e.shiftKey); | ||
384 | e.preventDefault(); | ||
385 | }else if(e.browserEvent.keyCode == e.UP){ | ||
386 | this.selectPrevious(e.shiftKey); | ||
387 | e.preventDefault(); | ||
388 | } | ||
389 | }, | ||
390 | |||
391 | /** @ignore */ | ||
392 | setRowClass : function(row, cssClass){ | ||
393 | if(this.isSelectable(row)){ | ||
394 | if(cssClass == 'selected'){ | ||
395 | YAHOO.util.Dom.removeClass(row, 'ygrid-row-over'); | ||
396 | YAHOO.util.Dom.addClass(row, 'ygrid-row-selected'); | ||
397 | }else if(cssClass == 'over'){ | ||
398 | YAHOO.util.Dom.removeClass(row, 'ygrid-row-selected'); | ||
399 | YAHOO.util.Dom.addClass(row, 'ygrid-row-over'); | ||
400 | }else if(cssClass == ''){ | ||
401 | YAHOO.util.Dom.removeClass(row, 'ygrid-row-selected'); | ||
402 | YAHOO.util.Dom.removeClass(row, 'ygrid-row-over'); | ||
403 | } | ||
404 | } | ||
405 | }, | ||
406 | |||
407 | /** @ignore */ | ||
408 | _removeSelected : function(row){ | ||
409 | var sr = this.selectedRows; | ||
410 | for (var i = 0; i < sr.length; i++) { | ||
411 | if (sr[i] === row){ | ||
412 | this.selectedRows.splice(i, 1); | ||
413 | this.selectedRowIds.splice(i, 1); | ||
414 | return; | ||
415 | } | ||
416 | } | ||
417 | } | ||
418 | }; | ||
419 | |||
420 | /** | ||
421 | @class YAHOO.ext.grid.SingleSelectionModel | ||
422 | @extends YAHOO.ext.grid.DefaultSelectionModel | ||
423 | Allows only one row to be selected at a time. | ||
424 | @constructor | ||
425 | * Create new SingleSelectionModel | ||
426 | */ | ||
427 | YAHOO.ext.grid.SingleSelectionModel = function(){ | ||
428 | YAHOO.ext.grid.SingleSelectionModel.superclass.constructor.call(this); | ||
429 | }; | ||
430 | |||
431 | YAHOO.extendX(YAHOO.ext.grid.SingleSelectionModel, YAHOO.ext.grid.DefaultSelectionModel); | ||
432 | |||
433 | /** @ignore */ | ||
434 | YAHOO.ext.grid.SingleSelectionModel.prototype.setRowState = function(row, selected){ | ||
435 | YAHOO.ext.grid.SingleSelectionModel.superclass.setRowState.call(this, row, selected, false); | ||
436 | }; | ||
437 | |||
438 | YAHOO.ext.grid.DisableSelectionModel = function(){ | ||
439 | YAHOO.ext.grid.DisableSelectionModel.superclass.constructor.call(this); | ||
440 | }; | ||
441 | |||
442 | YAHOO.extendX(YAHOO.ext.grid.DisableSelectionModel, YAHOO.ext.grid.DefaultSelectionModel); | ||
443 | |||
444 | YAHOO.ext.grid.DisableSelectionModel.prototype.initEvents = function(){ | ||
445 | }; | ||