Diffstat (limited to 'frontend/beta/js/YUI-extensions/grid/Grid.js') (more/less context) (ignore whitespace changes)
-rw-r--r-- | frontend/beta/js/YUI-extensions/grid/Grid.js | 965 |
1 files changed, 965 insertions, 0 deletions
diff --git a/frontend/beta/js/YUI-extensions/grid/Grid.js b/frontend/beta/js/YUI-extensions/grid/Grid.js new file mode 100644 index 0000000..46d5de4 --- a/dev/null +++ b/frontend/beta/js/YUI-extensions/grid/Grid.js | |||
@@ -0,0 +1,965 @@ | |||
1 | /** | ||
2 | * @class YAHOO.ext.grid.Grid | ||
3 | * @extends YAHOO.ext.util.Observable | ||
4 | * This class represents the primary interface of a component based grid control. | ||
5 | * <br><br>Usage:<pre><code> | ||
6 | var grid = new YAHOO.ext.grid.Grid('my-container-id', dataModel, columnModel); | ||
7 | // set any options | ||
8 | grid.render(); | ||
9 | // or using a config | ||
10 | var grid = new YAHOO.ext.grid.Grid('my-container-id', { | ||
11 | dataModel: myDataModel, | ||
12 | colModel: myColModel, | ||
13 | selModel: mySelectionModel, | ||
14 | autoSizeColumns: true, | ||
15 | monitorWindowResize: false, | ||
16 | trackMouseOver: true | ||
17 | }).render(); | ||
18 | * </code></pre> | ||
19 | * <b>Common Problems:</b><br/> | ||
20 | * - Grid does not resize properly when going smaller: Setting overflow hidden on the container | ||
21 | * element will correct this<br/> | ||
22 | * - If you get el.style[camel]= NaNpx or -2px or something related, be certain you have given your container element | ||
23 | * dimensions. The grid adapts to your container's size, if your container has no size defined then the results | ||
24 | * are unpredictable.<br/> | ||
25 | * - Do not render the grid into an element with display:none. Try using visibility:hidden. Otherwise there is no way for the | ||
26 | * grid to calculate dimensions/offsets.<br/> | ||
27 | * @requires YAHOO.util.Dom | ||
28 | * @requires YAHOO.util.Event | ||
29 | * @requires YAHOO.util.CustomEvent | ||
30 | * @requires YAHOO.ext.Element | ||
31 | * @requires YAHOO.ext.util.Browser | ||
32 | * @requires YAHOO.ext.util.CSS | ||
33 | * @requires YAHOO.ext.SplitBar | ||
34 | * @requires YAHOO.ext.EventObject | ||
35 | * @constructor | ||
36 | * @param {String/HTMLElement/YAHOO.ext.Element} container The element into which this grid will be rendered - | ||
37 | * The container MUST have some type of size defined for the grid to fill. The container will be | ||
38 | * automatically set to position relative if it isn't already. | ||
39 | * @param {Object} config A config object that sets properties on this grid OR the data model to bind to | ||
40 | * @param {Object} colModel (optional) The column model with info about this grid's columns | ||
41 | * @param {Object} selectionModel (optional) The selection model for this grid (defaults to DefaultSelectionModel) | ||
42 | */ | ||
43 | YAHOO.ext.grid.Grid = function(container, config, colModel, selectionModel){ | ||
44 | /** @private */ | ||
45 | this.container = YAHOO.ext.Element.get(container); | ||
46 | this.container.update(''); | ||
47 | this.container.setStyle('overflow', 'hidden'); | ||
48 | this.id = this.container.id; | ||
49 | this.rows = []; | ||
50 | this.rowCount = 0; | ||
51 | this.fieldId = null; | ||
52 | var dataModel = config; // for legacy pre config support | ||
53 | this.dataModel = dataModel; | ||
54 | this.colModel = colModel; | ||
55 | this.selModel = selectionModel; | ||
56 | this.activeEditor = null; | ||
57 | this.editingCell = null; | ||
58 | |||
59 | |||
60 | if(typeof config == 'object' && !config.getRowCount){// must be config object | ||
61 | YAHOO.ext.util.Config.apply(this, config); | ||
62 | } | ||
63 | |||
64 | /** @private */ | ||
65 | this.setValueDelegate = this.setCellValue.createDelegate(this); | ||
66 | |||
67 | /** @private */ | ||
68 | this.events = { | ||
69 | // raw events | ||
70 | /** | ||
71 | * @event click | ||
72 | * The raw click event for the entire grid. | ||
73 | * @param {YAHOO.ext.EventObject} e | ||
74 | */ | ||
75 | 'click' : true, | ||
76 | /** | ||
77 | * @event dblclick | ||
78 | * The raw dblclick event for the entire grid. | ||
79 | * @param {YAHOO.ext.EventObject} e | ||
80 | */ | ||
81 | 'dblclick' : true, | ||
82 | /** | ||
83 | * @event mousedown | ||
84 | * The raw mousedown event for the entire grid. | ||
85 | * @param {YAHOO.ext.EventObject} e | ||
86 | */ | ||
87 | 'mousedown' : true, | ||
88 | /** | ||
89 | * @event mouseup | ||
90 | * The raw mouseup event for the entire grid. | ||
91 | * @param {YAHOO.ext.EventObject} e | ||
92 | */ | ||
93 | 'mouseup' : true, | ||
94 | /** | ||
95 | * @event mouseover | ||
96 | * The raw mouseover event for the entire grid. | ||
97 | * @param {YAHOO.ext.EventObject} e | ||
98 | */ | ||
99 | 'mouseover' : true, | ||
100 | /** | ||
101 | * @event mouseout | ||
102 | * The raw mouseout event for the entire grid. | ||
103 | * @param {YAHOO.ext.EventObject} e | ||
104 | */ | ||
105 | 'mouseout' : true, | ||
106 | /** | ||
107 | * @event keypress | ||
108 | * The raw keypress event for the entire grid. | ||
109 | * @param {YAHOO.ext.EventObject} e | ||
110 | */ | ||
111 | 'keypress' : true, | ||
112 | /** | ||
113 | * @event keydown | ||
114 | * The raw keydown event for the entire grid. | ||
115 | * @param {YAHOO.ext.EventObject} e | ||
116 | */ | ||
117 | 'keydown' : true, | ||
118 | |||
119 | // custom events | ||
120 | |||
121 | /** | ||
122 | * @event cellclick | ||
123 | * Fires when a cell is clicked | ||
124 | * @param {Grid} this | ||
125 | * @param {Number} rowIndex | ||
126 | * @param {Number} columnIndex | ||
127 | * @param {YAHOO.ext.EventObject} e | ||
128 | */ | ||
129 | 'cellclick' : true, | ||
130 | /** | ||
131 | * @event celldblclick | ||
132 | * Fires when a cell is double clicked | ||
133 | * @param {Grid} this | ||
134 | * @param {Number} rowIndex | ||
135 | * @param {Number} columnIndex | ||
136 | * @param {YAHOO.ext.EventObject} e | ||
137 | */ | ||
138 | 'celldblclick' : true, | ||
139 | /** | ||
140 | * @event rowclick | ||
141 | * Fires when a row is clicked | ||
142 | * @param {Grid} this | ||
143 | * @param {Number} rowIndex | ||
144 | * @param {YAHOO.ext.EventObject} e | ||
145 | */ | ||
146 | 'rowclick' : true, | ||
147 | /** | ||
148 | * @event rowdblclick | ||
149 | * Fires when a row is double clicked | ||
150 | * @param {Grid} this | ||
151 | * @param {Number} rowIndex | ||
152 | * @param {YAHOO.ext.EventObject} e | ||
153 | */ | ||
154 | 'rowdblclick' : true, | ||
155 | /** | ||
156 | * @event headerclick | ||
157 | * Fires when a header is clicked | ||
158 | * @param {Grid} this | ||
159 | * @param {Number} columnIndex | ||
160 | * @param {YAHOO.ext.EventObject} e | ||
161 | */ | ||
162 | 'headerclick' : true, | ||
163 | /** | ||
164 | * @event rowcontextmenu | ||
165 | * Fires when a row is right clicked | ||
166 | * @param {Grid} this | ||
167 | * @param {Number} rowIndex | ||
168 | * @param {YAHOO.ext.EventObject} e | ||
169 | */ | ||
170 | 'rowcontextmenu' : true, | ||
171 | /** | ||
172 | * @event cellcontextmenu | ||
173 | * Fires when a cell is right clicked | ||
174 | * @param {Grid} this | ||
175 | * @param {Number} rowIndex | ||
176 | * @param {Number} cellIndex | ||
177 | * @param {YAHOO.ext.EventObject} e | ||
178 | */ | ||
179 | 'cellcontextmenu' : true, | ||
180 | /** | ||
181 | * @event headercontextmenu | ||
182 | * Fires when a header is right clicked | ||
183 | * @param {Grid} this | ||
184 | * @param {Number} columnIndex | ||
185 | * @param {YAHOO.ext.EventObject} e | ||
186 | */ | ||
187 | 'headercontextmenu' : true, | ||
188 | /** | ||
189 | * @event beforeedit | ||
190 | * Fires before a cell is edited | ||
191 | * @param {Grid} this | ||
192 | * @param {Number} rowIndex | ||
193 | * @param {Number} columnIndex | ||
194 | */ | ||
195 | 'beforeedit' : true, | ||
196 | /** | ||
197 | * @event afteredit | ||
198 | * Fires after a cell is edited | ||
199 | * @param {Grid} this | ||
200 | * @param {Number} rowIndex | ||
201 | * @param {Number} columnIndex | ||
202 | */ | ||
203 | 'afteredit' : true, | ||
204 | /** | ||
205 | * @event bodyscroll | ||
206 | * Fires when the body element is scrolled | ||
207 | * @param {Number} scrollLeft | ||
208 | * @param {Number} scrollTop | ||
209 | */ | ||
210 | 'bodyscroll' : true, | ||
211 | /** | ||
212 | * @event columnresize | ||
213 | * Fires when the user resizes a column | ||
214 | * @param {Number} columnIndex | ||
215 | * @param {Number} newSize | ||
216 | */ | ||
217 | 'columnresize' : true, | ||
218 | /** | ||
219 | * @event startdrag | ||
220 | * Fires when row(s) start being dragged | ||
221 | * @param {Grid} this | ||
222 | * @param {YAHOO.ext.GridDD} dd The drag drop object | ||
223 | * @param {event} e The raw browser event | ||
224 | */ | ||
225 | 'startdrag' : true, | ||
226 | /** | ||
227 | * @event enddrag | ||
228 | * Fires when a drag operation is complete | ||
229 | * @param {Grid} this | ||
230 | * @param {YAHOO.ext.GridDD} dd The drag drop object | ||
231 | * @param {event} e The raw browser event | ||
232 | */ | ||
233 | 'enddrag' : true, | ||
234 | /** | ||
235 | * @event dragdrop | ||
236 | * Fires when dragged row(s) are dropped on a valid DD target | ||
237 | * @param {Grid} this | ||
238 | * @param {YAHOO.ext.GridDD} dd The drag drop object | ||
239 | * @param {String} targetId The target drag drop object | ||
240 | * @param {event} e The raw browser event | ||
241 | */ | ||
242 | 'dragdrop' : true, | ||
243 | /** | ||
244 | * @event dragover | ||
245 | * Fires while row(s) are being dragged. "targetId" is the id of the Yahoo.util.DD object the selected rows are being dragged over. | ||
246 | * @param {Grid} this | ||
247 | * @param {YAHOO.ext.GridDD} dd The drag drop object | ||
248 | * @param {String} targetId The target drag drop object | ||
249 | * @param {event} e The raw browser event | ||
250 | */ | ||
251 | 'dragover' : true, | ||
252 | /** | ||
253 | * @event dragenter | ||
254 | * Fires when the dragged row(s) first cross another DD target while being dragged | ||
255 | * @param {Grid} this | ||
256 | * @param {YAHOO.ext.GridDD} dd The drag drop object | ||
257 | * @param {String} targetId The target drag drop object | ||
258 | * @param {event} e The raw browser event | ||
259 | */ | ||
260 | 'dragenter' : true, | ||
261 | /** | ||
262 | * @event dragout | ||
263 | * Fires when the dragged row(s) leave another DD target while being dragged | ||
264 | * @param {Grid} this | ||
265 | * @param {YAHOO.ext.GridDD} dd The drag drop object | ||
266 | * @param {String} targetId The target drag drop object | ||
267 | * @param {event} e The raw browser event | ||
268 | */ | ||
269 | 'dragout' : true | ||
270 | }; | ||
271 | }; | ||
272 | |||
273 | YAHOO.ext.grid.Grid.prototype = { | ||
274 | /** The minimum width a column can be resized to. (Defaults to 25) | ||
275 | * @type Number */ | ||
276 | minColumnWidth : 25, | ||
277 | |||
278 | /** True to automatically resize the columns to fit their content <b>on initial render</b> | ||
279 | * @type Boolean */ | ||
280 | autoSizeColumns : false, | ||
281 | |||
282 | /** True to measure headers with column data when auto sizing columns | ||
283 | * @type Boolean */ | ||
284 | autoSizeHeaders : false, | ||
285 | |||
286 | /** | ||
287 | * True to autoSize the grid when the window resizes - defaults to true | ||
288 | */ | ||
289 | monitorWindowResize : true, | ||
290 | |||
291 | /** If autoSizeColumns is on, maxRowsToMeasure can be used to limit the number of | ||
292 | * rows measured to get a columns size - defaults to 0 (all rows). | ||
293 | * @type Number */ | ||
294 | maxRowsToMeasure : 0, | ||
295 | |||
296 | /** True to highlight rows when the mouse is over (default is false) | ||
297 | * @type Boolean */ | ||
298 | trackMouseOver : false, | ||
299 | |||
300 | /** True to enable drag and drop of rows | ||
301 | * @type Boolean */ | ||
302 | enableDragDrop : false, | ||
303 | |||
304 | /** True to stripe the rows (default is true) | ||
305 | * @type Boolean */ | ||
306 | stripeRows : true, | ||
307 | /** True to fit the height of the grid container to the height of the data (defaults to false) | ||
308 | * @type Boolean */ | ||
309 | autoHeight : false, | ||
310 | |||
311 | /** True to fit the width of the grid container to the width of the columns (defaults to false) | ||
312 | * @type Boolean */ | ||
313 | autoWidth : false, | ||
314 | |||
315 | /** | ||
316 | * The view used by the grid. This can be set before a call to render(). | ||
317 | * Defaults to a YAHOO.ext.grid.GridView or PagedGridView depending on the data model. | ||
318 | * @type Object | ||
319 | */ | ||
320 | view : null, | ||
321 | |||
322 | /** A regular expression defining tagNames | ||
323 | * allowed to have text selection (Defaults to <code>/INPUT|TEXTAREA|SELECT/i</code>) */ | ||
324 | allowTextSelectionPattern : /INPUT|TEXTAREA|SELECT/i, | ||
325 | |||
326 | /** | ||
327 | * Called once after all setup has been completed and the grid is ready to be rendered. | ||
328 | * @return {YAHOO.ext.grid.Grid} this | ||
329 | */ | ||
330 | render : function(){ | ||
331 | if((!this.container.dom.offsetHeight || this.container.dom.offsetHeight < 20) | ||
332 | || this.container.getStyle('height') == 'auto'){ | ||
333 | this.autoHeight = true; | ||
334 | } | ||
335 | if((!this.container.dom.offsetWidth || this.container.dom.offsetWidth < 20)){ | ||
336 | this.autoWidth = true; | ||
337 | } | ||
338 | if(!this.view){ | ||
339 | if(this.dataModel.isPaged()){ | ||
340 | this.view = new YAHOO.ext.grid.PagedGridView(); | ||
341 | }else{ | ||
342 | this.view = new YAHOO.ext.grid.GridView(); | ||
343 | } | ||
344 | } | ||
345 | this.view.init(this); | ||
346 | this.el = getEl(this.view.render(), true); | ||
347 | var c = this.container; | ||
348 | c.mon("click", this.onClick, this, true); | ||
349 | c.mon("dblclick", this.onDblClick, this, true); | ||
350 | c.mon("contextmenu", this.onContextMenu, this, true); | ||
351 | c.mon("selectstart", this.cancelTextSelection, this, true); | ||
352 | c.mon("mousedown", this.cancelTextSelection, this, true); | ||
353 | c.mon("mousedown", this.onMouseDown, this, true); | ||
354 | c.mon("mouseup", this.onMouseUp, this, true); | ||
355 | if(this.trackMouseOver){ | ||
356 | this.el.mon("mouseover", this.onMouseOver, this, true); | ||
357 | this.el.mon("mouseout", this.onMouseOut, this, true); | ||
358 | } | ||
359 | c.mon("keypress", this.onKeyPress, this, true); | ||
360 | c.mon("keydown", this.onKeyDown, this, true); | ||
361 | this.init(); | ||
362 | return this; | ||
363 | }, | ||
364 | |||
365 | init : function(){ | ||
366 | this.rows = this.el.dom.rows; | ||
367 | if(!this.disableSelection){ | ||
368 | if(!this.selModel){ | ||
369 | this.selModel = new YAHOO.ext.grid.DefaultSelectionModel(this); | ||
370 | } | ||
371 | this.selModel.init(this); | ||
372 | this.selModel.onSelectionChange.subscribe(this.updateField, this, true); | ||
373 | }else{ | ||
374 | this.selModel = new YAHOO.ext.grid.DisableSelectionModel(this); | ||
375 | this.selModel.init(this); | ||
376 | } | ||
377 | |||
378 | if(this.enableDragDrop){ | ||
379 | this.dd = new YAHOO.ext.grid.GridDD(this, this.container.dom); | ||
380 | } | ||
381 | }, | ||
382 | |||
383 | /** | ||
384 | * Resets the grid for use with a new configuration and/or data and column models. After calling this function | ||
385 | * you will need to call render() again. Any listeners for this grid will be retained. | ||
386 | * Warning: any listeners manually attached (not through the grid) to the grid's container | ||
387 | * element will be removed. | ||
388 | * @param {Object} config Standard config object with properties to set on this grid | ||
389 | * @return {YAHOO.ext.grid.Grid} this | ||
390 | */ | ||
391 | reset : function(config){ | ||
392 | this.destroy(false, true); | ||
393 | YAHOO.ext.util.Config.apply(this, config); | ||
394 | return this; | ||
395 | }, | ||
396 | |||
397 | /** | ||
398 | * Destroy this grid. | ||
399 | * @param {Boolean} removeEl True to remove the element | ||
400 | */ | ||
401 | destroy : function(removeEl, keepListeners){ | ||
402 | var c = this.container; | ||
403 | c.removeAllListeners(); | ||
404 | this.view.destroy(); | ||
405 | YAHOO.ext.EventManager.removeResizeListener(this.view.onWindowResize, this.view); | ||
406 | this.view = null; | ||
407 | this.colModel.purgeListeners(); | ||
408 | if(!keepListeners){ | ||
409 | this.purgeListeners(); | ||
410 | } | ||
411 | c.update(''); | ||
412 | if(removeEl === true){ | ||
413 | c.remove(); | ||
414 | } | ||
415 | }, | ||
416 | |||
417 | /** | ||
418 | * Replace the current data model with a new one (experimental) | ||
419 | * @param {DataModel} dm The new data model | ||
420 | * @pram {Boolean} rerender true to render the grid rows from scratch | ||
421 | */ | ||
422 | setDataModel : function(dm, rerender){ | ||
423 | this.view.unplugDataModel(this.dataModel); | ||
424 | this.dataModel = dm; | ||
425 | this.view.plugDataModel(dm); | ||
426 | if(rerender){ | ||
427 | dm.fireEvent('datachanged'); | ||
428 | } | ||
429 | }, | ||
430 | |||
431 | onMouseDown : function(e){ | ||
432 | this.fireEvent('mousedown', e); | ||
433 | }, | ||
434 | |||
435 | onMouseUp : function(e){ | ||
436 | this.fireEvent('mouseup', e); | ||
437 | }, | ||
438 | |||
439 | onMouseOver : function(e){ | ||
440 | this.fireEvent('mouseover', e); | ||
441 | }, | ||
442 | |||
443 | onMouseOut : function(e){ | ||
444 | this.fireEvent('mouseout', e); | ||
445 | }, | ||
446 | |||
447 | onKeyPress : function(e){ | ||
448 | this.fireEvent('keypress', e); | ||
449 | }, | ||
450 | |||
451 | onKeyDown : function(e){ | ||
452 | this.fireEvent('keydown', e); | ||
453 | }, | ||
454 | |||
455 | fireEvent : YAHOO.ext.util.Observable.prototype.fireEvent, | ||
456 | on : YAHOO.ext.util.Observable.prototype.on, | ||
457 | addListener : YAHOO.ext.util.Observable.prototype.addListener, | ||
458 | delayedListener : YAHOO.ext.util.Observable.prototype.delayedListener, | ||
459 | removeListener : YAHOO.ext.util.Observable.prototype.removeListener, | ||
460 | purgeListeners : YAHOO.ext.util.Observable.prototype.purgeListeners, | ||
461 | bufferedListener : YAHOO.ext.util.Observable.prototype.bufferedListener, | ||
462 | |||
463 | onClick : function(e){ | ||
464 | this.fireEvent('click', e); | ||
465 | var target = e.getTarget(); | ||
466 | var row = this.getRowFromChild(target); | ||
467 | var cell = this.getCellFromChild(target); | ||
468 | var header = this.getHeaderFromChild(target); | ||
469 | if(cell){ | ||
470 | this.fireEvent('cellclick', this, row.rowIndex, cell.columnIndex, e); | ||
471 | } | ||
472 | if(row){ | ||
473 | this.fireEvent('rowclick', this, row.rowIndex, e); | ||
474 | } | ||
475 | if(header){ | ||
476 | this.fireEvent('headerclick', this, header.columnIndex, e); | ||
477 | } | ||
478 | }, | ||
479 | |||
480 | onContextMenu : function(e){ | ||
481 | var target = e.getTarget(); | ||
482 | var row = this.getRowFromChild(target); | ||
483 | var cell = this.getCellFromChild(target); | ||
484 | var header = this.getHeaderFromChild(target); | ||
485 | if(cell){ | ||
486 | this.fireEvent('cellcontextmenu', this, row.rowIndex, cell.columnIndex, e); | ||
487 | } | ||
488 | if(row){ | ||
489 | this.fireEvent('rowcontextmenu', this, row.rowIndex, e); | ||
490 | } | ||
491 | if(header){ | ||
492 | this.fireEvent('headercontextmenu', this, header.columnIndex, e); | ||
493 | } | ||
494 | e.preventDefault(); | ||
495 | }, | ||
496 | |||
497 | onDblClick : function(e){ | ||
498 | this.fireEvent('dblclick', e); | ||
499 | var target = e.getTarget(); | ||
500 | var row = this.getRowFromChild(target); | ||
501 | var cell = this.getCellFromChild(target); | ||
502 | if(row){ | ||
503 | this.fireEvent('rowdblclick', this, row.rowIndex, e); | ||
504 | } | ||
505 | if(cell){ | ||
506 | this.fireEvent('celldblclick', this, row.rowIndex, cell.columnIndex, e); | ||
507 | } | ||
508 | }, | ||
509 | |||
510 | /** | ||
511 | * Starts editing the specified for the specified row/column | ||
512 | * @param {Number} rowIndex | ||
513 | * @param {Number} colIndex | ||
514 | */ | ||
515 | startEditing : function(rowIndex, colIndex){ | ||
516 | var row = this.rows[rowIndex]; | ||
517 | var cell = row.childNodes[colIndex]; | ||
518 | this.stopEditing(); | ||
519 | setTimeout(this.doEdit.createDelegate(this, [row, cell]), 10); | ||
520 | }, | ||
521 | |||
522 | /** | ||
523 | * Stops any active editing | ||
524 | */ | ||
525 | stopEditing : function(){ | ||
526 | if(this.activeEditor){ | ||
527 | this.activeEditor.stopEditing(); | ||
528 | } | ||
529 | }, | ||
530 | |||
531 | /** @ignore */ | ||
532 | doEdit : function(row, cell){ | ||
533 | if(!row || !cell) return; | ||
534 | var cm = this.colModel; | ||
535 | var dm = this.dataModel; | ||
536 | var colIndex = cell.columnIndex; | ||
537 | var rowIndex = row.rowIndex; | ||
538 | if(cm.isCellEditable(colIndex, rowIndex)){ | ||
539 | var ed = cm.getCellEditor(colIndex, rowIndex); | ||
540 | if(ed){ | ||
541 | if(this.activeEditor){ | ||
542 | this.activeEditor.stopEditing(); | ||
543 | } | ||
544 | this.fireEvent('beforeedit', this, rowIndex, colIndex); | ||
545 | this.activeEditor = ed; | ||
546 | this.editingCell = cell; | ||
547 | this.view.ensureVisible(row, true); | ||
548 | try{ | ||
549 | cell.focus(); | ||
550 | }catch(e){} | ||
551 | ed.init(this, this.el.dom.parentNode, this.setValueDelegate); | ||
552 | var value = dm.getValueAt(rowIndex, cm.getDataIndex(colIndex)); | ||
553 | // set timeout so firefox stops editing before starting a new edit | ||
554 | setTimeout(ed.startEditing.createDelegate(ed, [value, row, cell]), 1); | ||
555 | } | ||
556 | } | ||
557 | }, | ||
558 | |||
559 | setCellValue : function(value, rowIndex, colIndex){ | ||
560 | this.dataModel.setValueAt(value, rowIndex, this.colModel.getDataIndex(colIndex)); | ||
561 | this.fireEvent('afteredit', this, rowIndex, colIndex); | ||
562 | }, | ||
563 | |||
564 | /** @ignore Called when text selection starts or mousedown to prevent default */ | ||
565 | cancelTextSelection : function(e){ | ||
566 | var target = e.getTarget(); | ||
567 | if(target && target != this.el.dom.parentNode && !this.allowTextSelectionPattern.test(target.tagName)){ | ||
568 | e.preventDefault(); | ||
569 | } | ||
570 | }, | ||
571 | |||
572 | /** | ||
573 | * Causes the grid to manually recalculate it's dimensions. Generally this is done automatically, | ||
574 | * but if manual update is required this method will initiate it. | ||
575 | */ | ||
576 | autoSize : function(){ | ||
577 | this.view.updateWrapHeight(); | ||
578 | this.view.adjustForScroll(); | ||
579 | }, | ||
580 | |||
581 | /** | ||
582 | * Scrolls the grid to the specified row | ||
583 | * @param {Number/HTMLElement} row The row object or index of the row | ||
584 | */ | ||
585 | scrollTo : function(row){ | ||
586 | if(typeof row == 'number'){ | ||
587 | row = this.rows[row]; | ||
588 | } | ||
589 | this.view.ensureVisible(row, true); | ||
590 | }, | ||
591 | |||
592 | /** @private */ | ||
593 | getEditingCell : function(){ | ||
594 | return this.editingCell; | ||
595 | }, | ||
596 | |||
597 | /** | ||
598 | * Binds this grid to the field with the specified id. Initially reads and parses the comma | ||
599 | * delimited ids in the field and selects those items. All selections made in the grid | ||
600 | * will be persisted to the field by their ids comma delimited. | ||
601 | * @param {String} The id of the field to bind to | ||
602 | */ | ||
603 | bindToField : function(fieldId){ | ||
604 | this.fieldId = fieldId; | ||
605 | this.readField(); | ||
606 | }, | ||
607 | |||
608 | /** @private */ | ||
609 | updateField : function(){ | ||
610 | if(this.fieldId){ | ||
611 | var field = YAHOO.util.Dom.get(this.fieldId); | ||
612 | field.value = this.getSelectedRowIds().join(','); | ||
613 | } | ||
614 | }, | ||
615 | |||
616 | /** | ||
617 | * Causes the grid to read and select the ids from the bound field - See {@link #bindToField}. | ||
618 | */ | ||
619 | readField : function(){ | ||
620 | if(this.fieldId){ | ||
621 | var field = YAHOO.util.Dom.get(this.fieldId); | ||
622 | var values = field.value.split(','); | ||
623 | var rows = this.getRowsById(values); | ||
624 | this.selModel.selectRows(rows, false); | ||
625 | } | ||
626 | }, | ||
627 | |||
628 | /** | ||
629 | * Returns the table row at the specified index | ||
630 | * @param {Number} index | ||
631 | * @return {HTMLElement} | ||
632 | */ | ||
633 | getRow : function(index){ | ||
634 | return this.rows[index]; | ||
635 | }, | ||
636 | |||
637 | /** | ||
638 | * Returns the rows that have the specified id(s). The id value for a row is provided | ||
639 | * by the DataModel. See {@link YAHOO.ext.grid.DefaultDataModel#getRowId}. | ||
640 | * @param {String/Array} An id to find or an array of ids | ||
641 | * @return {HtmlElement/Array} If one id was passed in, it returns one result. | ||
642 | * If an array of ids was specified, it returns an Array of HTMLElements | ||
643 | */ | ||
644 | getRowsById : function(id){ | ||
645 | var dm = this.dataModel; | ||
646 | if(!(id instanceof Array)){ | ||
647 | for(var i = 0; i < this.rows.length; i++){ | ||
648 | if(dm.getRowId(i) == id){ | ||
649 | return this.rows[i]; | ||
650 | } | ||
651 | } | ||
652 | return null; | ||
653 | } | ||
654 | var found = []; | ||
655 | var re = "^(?:"; | ||
656 | for(var i = 0; i < id.length; i++){ | ||
657 | re += id[i]; | ||
658 | if(i != id.length-1) re += "|"; | ||
659 | } | ||
660 | var regex = new RegExp(re + ")$"); | ||
661 | for(var i = 0; i < this.rows.length; i++){ | ||
662 | if(regex.test(dm.getRowId(i))){ | ||
663 | found.push(this.rows[i]); | ||
664 | } | ||
665 | } | ||
666 | return found; | ||
667 | }, | ||
668 | |||
669 | /** | ||
670 | * Returns the row that comes after the specified row - text nodes are skipped. | ||
671 | * @param {HTMLElement} row | ||
672 | * @return {HTMLElement} | ||
673 | */ | ||
674 | getRowAfter : function(row){ | ||
675 | return this.getSibling('next', row); | ||
676 | }, | ||
677 | |||
678 | /** | ||
679 | * Returns the row that comes before the specified row - text nodes are skipped. | ||
680 | * @param {HTMLElement} row | ||
681 | * @return {HTMLElement} | ||
682 | */ | ||
683 | getRowBefore : function(row){ | ||
684 | return this.getSibling('previous', row); | ||
685 | }, | ||
686 | |||
687 | /** | ||
688 | * Returns the cell that comes after the specified cell - text nodes are skipped. | ||
689 | * @param {HTMLElement} cell | ||
690 | * @param {Boolean} includeHidden | ||
691 | * @return {HTMLElement} | ||
692 | */ | ||
693 | getCellAfter : function(cell, includeHidden){ | ||
694 | var next = this.getSibling('next', cell); | ||
695 | if(next && !includeHidden && this.colModel.isHidden(next.columnIndex)){ | ||
696 | return this.getCellAfter(next); | ||
697 | } | ||
698 | return next; | ||
699 | }, | ||
700 | |||
701 | /** | ||
702 | * Returns the cell that comes before the specified cell - text nodes are skipped. | ||
703 | * @param {HTMLElement} cell | ||
704 | * @param {Boolean} includeHidden | ||
705 | * @return {HTMLElement} | ||
706 | */ | ||
707 | getCellBefore : function(cell, includeHidden){ | ||
708 | var prev = this.getSibling('previous', cell); | ||
709 | if(prev && !includeHidden && this.colModel.isHidden(prev.columnIndex)){ | ||
710 | return this.getCellBefore(prev); | ||
711 | } | ||
712 | return prev; | ||
713 | }, | ||
714 | |||
715 | /** | ||
716 | * Returns the last cell for the row - text nodes and hidden columns are skipped. | ||
717 | * @param {HTMLElement} row | ||
718 | * @param {Boolean} includeHidden | ||
719 | * @return {HTMLElement} | ||
720 | */ | ||
721 | getLastCell : function(row, includeHidden){ | ||
722 | var cell = this.getElement('previous', row.lastChild); | ||
723 | if(cell && !includeHidden && this.colModel.isHidden(cell.columnIndex)){ | ||
724 | return this.getCellBefore(cell); | ||
725 | } | ||
726 | return cell; | ||
727 | }, | ||
728 | |||
729 | /** | ||
730 | * Returns the first cell for the row - text nodes and hidden columns are skipped. | ||
731 | * @param {HTMLElement} row | ||
732 | * @param {Boolean} includeHidden | ||
733 | * @return {HTMLElement} | ||
734 | */ | ||
735 | getFirstCell : function(row, includeHidden){ | ||
736 | var cell = this.getElement('next', row.firstChild); | ||
737 | if(cell && !includeHidden && this.colModel.isHidden(cell.columnIndex)){ | ||
738 | return this.getCellAfter(cell); | ||
739 | } | ||
740 | return cell; | ||
741 | }, | ||
742 | |||
743 | /** | ||
744 | * @private | ||
745 | * Gets siblings, skipping text nodes | ||
746 | * @param {String} type The direction to walk: 'next' or 'previous' | ||
747 | * @param {HTMLElement} node | ||
748 | */ | ||
749 | getSibling : function(type, node){ | ||
750 | if(!node) return null; | ||
751 | type += 'Sibling'; | ||
752 | var n = node[type]; | ||
753 | while(n && n.nodeType != 1){ | ||
754 | n = n[type]; | ||
755 | } | ||
756 | return n; | ||
757 | }, | ||
758 | |||
759 | /** | ||
760 | * Returns node if node is an HTMLElement else walks the siblings in direction looking for | ||
761 | * a node that is an element | ||
762 | * @param {String} direction The direction to walk: 'next' or 'previous' | ||
763 | * @private | ||
764 | */ | ||
765 | getElement : function(direction, node){ | ||
766 | if(!node || node.nodeType == 1) return node; | ||
767 | else return this.getSibling(direction, node); | ||
768 | }, | ||
769 | |||
770 | /** | ||
771 | * @private | ||
772 | */ | ||
773 | getElementFromChild : function(childEl, parentClass){ | ||
774 | if(!childEl || (YAHOO.util.Dom.hasClass(childEl, parentClass))){ | ||
775 | return childEl; | ||
776 | } | ||
777 | var p = childEl.parentNode; | ||
778 | var b = document.body; | ||
779 | while(p && p != b){ | ||
780 | if(YAHOO.util.Dom.hasClass(p, parentClass)){ | ||
781 | return p; | ||
782 | } | ||
783 | p = p.parentNode; | ||
784 | } | ||
785 | return null; | ||
786 | }, | ||
787 | |||
788 | /** | ||
789 | * Returns the row that contains the specified child element. | ||
790 | * @param {HTMLElement} childEl | ||
791 | * @return {HTMLElement} | ||
792 | */ | ||
793 | getRowFromChild : function(childEl){ | ||
794 | return this.getElementFromChild(childEl, 'ygrid-row'); | ||
795 | }, | ||
796 | |||
797 | /** | ||
798 | * Returns the cell that contains the specified child element. | ||
799 | * @param {HTMLElement} childEl | ||
800 | * @return {HTMLElement} | ||
801 | */ | ||
802 | getCellFromChild : function(childEl){ | ||
803 | return this.getElementFromChild(childEl, 'ygrid-col'); | ||
804 | }, | ||
805 | |||
806 | |||
807 | /** | ||
808 | * Returns the header element that contains the specified child element. | ||
809 | * @param {HTMLElement} childEl | ||
810 | * @return {HTMLElement} | ||
811 | */ | ||
812 | getHeaderFromChild : function(childEl){ | ||
813 | return this.getElementFromChild(childEl, 'ygrid-hd'); | ||
814 | }, | ||
815 | |||
816 | /** | ||
817 | * Convenience method for getSelectionModel().getSelectedRows() - | ||
818 | * See <small>{@link YAHOO.ext.grid.DefaultSelectionModel#getSelectedRows}</small> for more details. | ||
819 | * @return {Array} | ||
820 | */ | ||
821 | getSelectedRows : function(){ | ||
822 | return this.selModel.getSelectedRows(); | ||
823 | }, | ||
824 | |||
825 | /** | ||
826 | * Convenience method for getSelectionModel().getSelectedRows()[0] - | ||
827 | * See <small>{@link YAHOO.ext.grid.DefaultSelectionModel#getSelectedRows}</small> for more details. | ||
828 | * @return {HTMLElement} | ||
829 | */ | ||
830 | getSelectedRow : function(){ | ||
831 | if(this.selModel.hasSelection()){ | ||
832 | return this.selModel.getSelectedRows()[0]; | ||
833 | } | ||
834 | return null; | ||
835 | }, | ||
836 | |||
837 | /** | ||
838 | * Get the selected row indexes | ||
839 | * @return {Array} Array of indexes | ||
840 | */ | ||
841 | getSelectedRowIndexes : function(){ | ||
842 | var a = []; | ||
843 | var rows = this.selModel.getSelectedRows(); | ||
844 | for(var i = 0; i < rows.length; i++) { | ||
845 | a[i] = rows[i].rowIndex; | ||
846 | } | ||
847 | return a; | ||
848 | }, | ||
849 | |||
850 | /** | ||
851 | * Gets the first selected row or -1 if none are selected | ||
852 | * @return {Number} | ||
853 | */ | ||
854 | getSelectedRowIndex : function(){ | ||
855 | if(this.selModel.hasSelection()){ | ||
856 | return this.selModel.getSelectedRows()[0].rowIndex; | ||
857 | } | ||
858 | return -1; | ||
859 | }, | ||
860 | |||
861 | /** | ||
862 | * Convenience method for getSelectionModel().getSelectedRowIds()[0] - | ||
863 | * See <small>{@link YAHOO.ext.grid.DefaultSelectionModel#getSelectedRowIds}</small> for more details. | ||
864 | * @return {String} | ||
865 | */ | ||
866 | getSelectedRowId : function(){ | ||
867 | if(this.selModel.hasSelection()){ | ||
868 | return this.selModel.getSelectedRowIds()[0]; | ||
869 | } | ||
870 | return null; | ||
871 | }, | ||
872 | |||
873 | /** | ||
874 | * Convenience method for getSelectionModel().getSelectedRowIds() - | ||
875 | * See <small>{@link YAHOO.ext.grid.DefaultSelectionModel#getSelectedRowIds}</small> for more details. | ||
876 | * @return {Array} | ||
877 | */ | ||
878 | getSelectedRowIds : function(){ | ||
879 | return this.selModel.getSelectedRowIds(); | ||
880 | }, | ||
881 | |||
882 | /** | ||
883 | * Convenience method for getSelectionModel().clearSelections() - | ||
884 | * See <small>{@link YAHOO.ext.grid.DefaultSelectionModel#clearSelections}</small> for more details. | ||
885 | */ | ||
886 | clearSelections : function(){ | ||
887 | this.selModel.clearSelections(); | ||
888 | }, | ||
889 | |||
890 | |||
891 | /** | ||
892 | * Convenience method for getSelectionModel().selectAll() - | ||
893 | * See <small>{@link YAHOO.ext.grid.DefaultSelectionModel#selectAll}</small> for more details. | ||
894 | */ | ||
895 | selectAll : function(){ | ||
896 | this.selModel.selectAll(); | ||
897 | }, | ||
898 | |||
899 | |||
900 | /** | ||
901 | * Convenience method for getSelectionModel().getCount() - | ||
902 | * See <small>{@link YAHOO.ext.grid.DefaultSelectionModel#getCount}</small> for more details. | ||
903 | * @return {Number} | ||
904 | */ | ||
905 | getSelectionCount : function(){ | ||
906 | return this.selModel.getCount(); | ||
907 | }, | ||
908 | |||
909 | /** | ||
910 | * Convenience method for getSelectionModel().hasSelection() - | ||
911 | * See <small>{@link YAHOO.ext.grid.DefaultSelectionModel#hasSelection}</small> for more details. | ||
912 | * @return {Boolean} | ||
913 | */ | ||
914 | hasSelection : function(){ | ||
915 | return this.selModel.hasSelection(); | ||
916 | }, | ||
917 | |||
918 | /** | ||
919 | * Returns the grid's SelectionModel. | ||
920 | * @return {SelectionModel} | ||
921 | */ | ||
922 | getSelectionModel : function(){ | ||
923 | if(!this.selModel){ | ||
924 | this.selModel = new DefaultSelectionModel(); | ||
925 | } | ||
926 | return this.selModel; | ||
927 | }, | ||
928 | |||
929 | /** | ||
930 | * Returns the grid's DataModel. | ||
931 | * @return {DataModel} | ||
932 | */ | ||
933 | getDataModel : function(){ | ||
934 | return this.dataModel; | ||
935 | }, | ||
936 | |||
937 | /** | ||
938 | * Returns the grid's ColumnModel. | ||
939 | * @return {ColumnModel} | ||
940 | */ | ||
941 | getColumnModel : function(){ | ||
942 | return this.colModel; | ||
943 | }, | ||
944 | |||
945 | /** | ||
946 | * Returns the grid's GridView object. | ||
947 | * @return {GridView} | ||
948 | */ | ||
949 | getView : function(){ | ||
950 | return this.view; | ||
951 | }, | ||
952 | /** | ||
953 | * Called to get grid's drag proxy text, by default returns this.ddText. | ||
954 | * @return {String} | ||
955 | */ | ||
956 | getDragDropText : function(){ | ||
957 | return this.ddText.replace('%0', this.selModel.getCount()); | ||
958 | } | ||
959 | }; | ||
960 | /** | ||
961 | * Configures the text is the drag proxy (defaults to "%0 selected row(s)"). | ||
962 | * %0 is replaced with the number of selected rows. | ||
963 | * @type String | ||
964 | */ | ||
965 | YAHOO.ext.grid.Grid.prototype.ddText = "%0 selected row(s)"; | ||