Upgrade to ExtJS 3.0.0 - Released 07/06/2009
[extjs.git] / src / widgets / grid / GridPanel.js
1 /*!
2  * Ext JS Library 3.0.0
3  * Copyright(c) 2006-2009 Ext JS, LLC
4  * licensing@extjs.com
5  * http://www.extjs.com/license
6  */
7 /**\r
8  * @class Ext.grid.GridPanel\r
9  * @extends Ext.Panel\r
10  * <p>This class represents the primary interface of a component based grid control to represent data\r
11  * in a tabular format of rows and columns. The GridPanel is composed of the following:</p>\r
12  * <div class="mdetail-params"><ul>\r
13  * <li><b>{@link Ext.data.Store Store}</b> : The Model holding the data records (rows)\r
14  * <div class="sub-desc"></div></li>\r
15  * <li><b>{@link Ext.grid.ColumnModel Column model}</b> : Column makeup\r
16  * <div class="sub-desc"></div></li>\r
17  * <li><b>{@link Ext.grid.GridView View}</b> : Encapsulates the user interface \r
18  * <div class="sub-desc"></div></li>\r
19  * <li><b>{@link Ext.grid.AbstractSelectionModel selection model}</b> : Selection behavior \r
20  * <div class="sub-desc"></div></li>\r
21  * </ul></div>\r
22  * <p>Example usage:</p>\r
23  * <pre><code>\r
24 var grid = new Ext.grid.GridPanel({\r
25     {@link #store}: new (@link Ext.data.Store}({\r
26         {@link Ext.data.Store#autoDestroy autoDestroy}: true,\r
27         {@link Ext.data.Store#reader reader}: reader,\r
28         {@link Ext.data.Store#data data}: xg.dummyData\r
29     }),\r
30     {@link #columns}: [\r
31         {id: 'company', header: 'Company', width: 200, sortable: true, dataIndex: 'company'},\r
32         {header: 'Price', width: 120, sortable: true, renderer: Ext.util.Format.usMoney, dataIndex: 'price'},\r
33         {header: 'Change', width: 120, sortable: true, dataIndex: 'change'},\r
34         {header: '% Change', width: 120, sortable: true, dataIndex: 'pctChange'},\r
35         // instead of specifying renderer: Ext.util.Format.dateRenderer('m/d/Y') use xtype\r
36         {header: 'Last Updated', width: 135, sortable: true, dataIndex: 'lastChange', xtype: 'datecolumn', format: 'M d, Y'}\r
37     ],\r
38     {@link #viewConfig}: {\r
39         {@link Ext.grid.GridView#forceFit forceFit}: true,\r
40 \r
41 //      Return CSS class to apply to rows depending upon data values\r
42         {@link Ext.grid.GridView#getRowClass getRowClass}: function(record, index) {\r
43             var c = record.{@link Ext.data.Record#get get}('change');\r
44             if (c < 0) {\r
45                 return 'price-fall';\r
46             } else if (c > 0) {\r
47                 return 'price-rise';\r
48             }\r
49         }\r
50     },\r
51     {@link #sm}: new Ext.grid.RowSelectionModel({singleSelect:true}),\r
52     width: 600,\r
53     height: 300,\r
54     frame: true,\r
55     title: 'Framed with Row Selection and Horizontal Scrolling',\r
56     iconCls: 'icon-grid'\r
57 });\r
58  * </code></pre>\r
59  * <p><b><u>Notes:</u></b></p>\r
60  * <div class="mdetail-params"><ul>\r
61  * <li>Although this class inherits many configuration options from base classes, some of them\r
62  * (such as autoScroll, autoWidth, layout, items, etc) are not used by this class, and will\r
63  * have no effect.</li>\r
64  * <li>A grid <b>requires</b> a width in which to scroll its columns, and a height in which to\r
65  * scroll its rows. These dimensions can either be set explicitly through the\r
66  * <tt>{@link Ext.BoxComponent#height height}</tt> and <tt>{@link Ext.BoxComponent#width width}</tt>\r
67  * configuration options or implicitly set by using the grid as a child item of a\r
68  * {@link Ext.Container Container} which will have a {@link Ext.Container#layout layout manager}\r
69  * provide the sizing of its child items (for example the Container of the Grid may specify\r
70  * <tt>{@link Ext.Container#layout layout}:'fit'</tt>).</li>\r
71  * <li>To access the data in a Grid, it is necessary to use the data model encapsulated\r
72  * by the {@link #store Store}. See the {@link #cellclick} event for more details.</li>\r
73  * </ul></div>\r
74  * @constructor\r
75  * @param {Object} config The config object\r
76  * @xtype grid\r
77  */\r
78 Ext.grid.GridPanel = Ext.extend(Ext.Panel, {\r
79     /**\r
80      * @cfg {String} autoExpandColumn\r
81      * <p>The <tt>{@link Ext.grid.Column#id id}</tt> of a {@link Ext.grid.Column column} in\r
82      * this grid that should expand to fill unused space. This value specified here can not\r
83      * be <tt>0</tt>.</p>\r
84      * <br><p><b>Note</b>: If the Grid's {@link Ext.grid.GridView view} is configured with\r
85      * <tt>{@link Ext.grid.GridView#forceFit forceFit}=true</tt> the <tt>autoExpandColumn</tt>\r
86      * is ignored. See {@link Ext.grid.Column}.<tt>{@link Ext.grid.Column#width width}</tt>\r
87      * for additional details.</p>\r
88      * <p>See <tt>{@link #autoExpandMax}</tt> and <tt>{@link #autoExpandMin}</tt> also.</p>\r
89      */\r
90     autoExpandColumn : false,\r
91     /**\r
92      * @cfg {Number} autoExpandMax The maximum width the <tt>{@link #autoExpandColumn}</tt>\r
93      * can have (if enabled). Defaults to <tt>1000</tt>.\r
94      */\r
95     autoExpandMax : 1000,\r
96     /**\r
97      * @cfg {Number} autoExpandMin The minimum width the <tt>{@link #autoExpandColumn}</tt>\r
98      * can have (if enabled). Defaults to <tt>50</tt>.\r
99      */\r
100     autoExpandMin : 50,\r
101     /**\r
102      * @cfg {Boolean} columnLines <tt>true</tt> to add css for column separation lines.\r
103      * Default is <tt>false</tt>.\r
104      */\r
105     columnLines : false,\r
106     /**\r
107      * @cfg {Object} cm Shorthand for <tt>{@link #colModel}</tt>.\r
108      */\r
109     /**\r
110      * @cfg {Object} colModel The {@link Ext.grid.ColumnModel} to use when rendering the grid (required).\r
111      */\r
112     /**\r
113      * @cfg {Array} columns An array of {@link Ext.grid.Column columns} to auto create a\r
114      * {@link Ext.grid.ColumnModel}.  The ColumnModel may be explicitly created via the\r
115      * <tt>{@link #colModel}</tt> configuration property.\r
116      */\r
117     /**\r
118      * @cfg {String} ddGroup The DD group this GridPanel belongs to. Defaults to <tt>'GridDD'</tt> if not specified.\r
119      */\r
120     /**\r
121      * @cfg {String} ddText\r
122      * Configures the text in the drag proxy.  Defaults to:\r
123      * <pre><code>\r
124      * ddText : '{0} selected row{1}'\r
125      * </code></pre>\r
126      * <tt>{0}</tt> is replaced with the number of selected rows.\r
127      */\r
128     ddText : '{0} selected row{1}',\r
129     /**\r
130      * @cfg {Boolean} deferRowRender <P>Defaults to <tt>true</tt> to enable deferred row rendering.</p>\r
131      * <p>This allows the GridPanel to be initially rendered empty, with the expensive update of the row\r
132      * structure deferred so that layouts with GridPanels appear more quickly.</p>\r
133      */\r
134     deferRowRender : true,\r
135     /**\r
136      * @cfg {Boolean} disableSelection <p><tt>true</tt> to disable selections in the grid. Defaults to <tt>false</tt>.</p>\r
137      * <p>Ignored if a {@link #selModel SelectionModel} is specified.</p>\r
138      */\r
139     /**\r
140      * @cfg {Boolean} enableColumnResize <tt>false</tt> to turn off column resizing for the whole grid. Defaults to <tt>true</tt>.\r
141      */\r
142     /**\r
143      * @cfg {Boolean} enableColumnHide Defaults to <tt>true</tt> to enable hiding of columns with the header context menu.\r
144      */\r
145     enableColumnHide : true,\r
146     /**\r
147      * @cfg {Boolean} enableColumnMove Defaults to <tt>true</tt> to enable drag and drop reorder of columns. <tt>false</tt>\r
148      * to turn off column reordering via drag drop.\r
149      */\r
150     enableColumnMove : true,\r
151     /**\r
152      * @cfg {Boolean} enableDragDrop <p>Enables dragging of the selected rows of the GridPanel. Defaults to <tt>false</tt>.</p>\r
153      * <p>Setting this to <b><tt>true</tt></b> causes this GridPanel's {@link #getView GridView} to\r
154      * create an instance of {@link Ext.grid.GridDragZone}. <b>Note</b>: this is available only <b>after</b>\r
155      * the Grid has been rendered as the GridView's <tt>{@link Ext.grid.GridView#dragZone dragZone}</tt>\r
156      * property.</p>\r
157      * <p>A cooperating {@link Ext.dd.DropZone DropZone} must be created who's implementations of\r
158      * {@link Ext.dd.DropZone#onNodeEnter onNodeEnter}, {@link Ext.dd.DropZone#onNodeOver onNodeOver},\r
159      * {@link Ext.dd.DropZone#onNodeOut onNodeOut} and {@link Ext.dd.DropZone#onNodeDrop onNodeDrop} are able\r
160      * to process the {@link Ext.grid.GridDragZone#getDragData data} which is provided.</p>\r
161      */\r
162     enableDragDrop : false,\r
163     /**\r
164      * @cfg {Boolean} enableHdMenu Defaults to <tt>true</tt> to enable the drop down button for menu in the headers.\r
165      */\r
166     enableHdMenu : true,\r
167     /**\r
168      * @cfg {Boolean} hideHeaders True to hide the grid's header. Defaults to <code>false</code>.\r
169      */\r
170     /**\r
171      * @cfg {Object} loadMask An {@link Ext.LoadMask} config or true to mask the grid while\r
172      * loading. Defaults to <code>false</code>.\r
173      */\r
174     loadMask : false,\r
175     /**\r
176      * @cfg {Number} maxHeight Sets the maximum height of the grid - ignored if <tt>autoHeight</tt> is not on.\r
177      */\r
178     /**\r
179      * @cfg {Number} minColumnWidth The minimum width a column can be resized to. Defaults to <tt>25</tt>.\r
180      */\r
181     minColumnWidth : 25,\r
182     /**\r
183      * @cfg {Object} sm Shorthand for <tt>{@link #selModel}</tt>.\r
184      */\r
185     /**\r
186      * @cfg {Object} selModel Any subclass of {@link Ext.grid.AbstractSelectionModel} that will provide\r
187      * the selection model for the grid (defaults to {@link Ext.grid.RowSelectionModel} if not specified).\r
188      */\r
189     /**\r
190      * @cfg {Ext.data.Store} store The {@link Ext.data.Store} the grid should use as its data source (required).\r
191      */\r
192     /**\r
193      * @cfg {Boolean} stripeRows <tt>true</tt> to stripe the rows. Default is <tt>false</tt>.\r
194      * <p>This causes the CSS class <tt><b>x-grid3-row-alt</b></tt> to be added to alternate rows of\r
195      * the grid. A default CSS rule is provided which sets a background colour, but you can override this\r
196      * with a rule which either overrides the <b>background-color</b> style using the '!important'\r
197      * modifier, or which uses a CSS selector of higher specificity.</p>\r
198      */\r
199     stripeRows : false,\r
200     /**\r
201      * @cfg {Boolean} trackMouseOver True to highlight rows when the mouse is over. Default is <tt>true</tt>\r
202      * for GridPanel, but <tt>false</tt> for EditorGridPanel.\r
203      */\r
204     trackMouseOver : true,\r
205     /**\r
206      * @cfg {Array} stateEvents\r
207      * An array of events that, when fired, should trigger this component to save its state.\r
208      * Defaults to:<pre><code>\r
209      * stateEvents: ['columnmove', 'columnresize', 'sortchange']\r
210      * </code></pre>\r
211      * <p>These can be any types of events supported by this component, including browser or\r
212      * custom events (e.g., <tt>['click', 'customerchange']</tt>).</p>\r
213      * <p>See {@link Ext.Component#stateful} for an explanation of saving and restoring\r
214      * Component state.</p>\r
215      */\r
216     stateEvents : ['columnmove', 'columnresize', 'sortchange'],\r
217     /**\r
218      * @cfg {Object} view The {@link Ext.grid.GridView} used by the grid. This can be set\r
219      * before a call to {@link Ext.Component#render render()}.\r
220      */\r
221     view : null,\r
222     /**\r
223      * @cfg {Object} viewConfig A config object that will be applied to the grid's UI view.  Any of\r
224      * the config options available for {@link Ext.grid.GridView} can be specified here. This option\r
225      * is ignored if <tt>{@link #view}</tt> is specified.\r
226      */\r
227 \r
228     // private\r
229     rendered : false,\r
230     // private\r
231     viewReady : false,\r
232 \r
233     // private\r
234     initComponent : function(){\r
235         Ext.grid.GridPanel.superclass.initComponent.call(this);\r
236 \r
237         if(this.columnLines){\r
238             this.cls = (this.cls || '') + ' x-grid-with-col-lines';\r
239         }\r
240         // override any provided value since it isn't valid\r
241         // and is causing too many bug reports ;)\r
242         this.autoScroll = false;\r
243         this.autoWidth = false;\r
244 \r
245         if(Ext.isArray(this.columns)){\r
246             this.colModel = new Ext.grid.ColumnModel(this.columns);\r
247             delete this.columns;\r
248         }\r
249 \r
250         // check and correct shorthanded configs\r
251         if(this.ds){\r
252             this.store = this.ds;\r
253             delete this.ds;\r
254         }\r
255         if(this.cm){\r
256             this.colModel = this.cm;\r
257             delete this.cm;\r
258         }\r
259         if(this.sm){\r
260             this.selModel = this.sm;\r
261             delete this.sm;\r
262         }\r
263         this.store = Ext.StoreMgr.lookup(this.store);\r
264 \r
265         this.addEvents(\r
266             // raw events\r
267             /**\r
268              * @event click\r
269              * The raw click event for the entire grid.\r
270              * @param {Ext.EventObject} e\r
271              */\r
272             'click',\r
273             /**\r
274              * @event dblclick\r
275              * The raw dblclick event for the entire grid.\r
276              * @param {Ext.EventObject} e\r
277              */\r
278             'dblclick',\r
279             /**\r
280              * @event contextmenu\r
281              * The raw contextmenu event for the entire grid.\r
282              * @param {Ext.EventObject} e\r
283              */\r
284             'contextmenu',\r
285             /**\r
286              * @event mousedown\r
287              * The raw mousedown event for the entire grid.\r
288              * @param {Ext.EventObject} e\r
289              */\r
290             'mousedown',\r
291             /**\r
292              * @event mouseup\r
293              * The raw mouseup event for the entire grid.\r
294              * @param {Ext.EventObject} e\r
295              */\r
296             'mouseup',\r
297             /**\r
298              * @event mouseover\r
299              * The raw mouseover event for the entire grid.\r
300              * @param {Ext.EventObject} e\r
301              */\r
302             'mouseover',\r
303             /**\r
304              * @event mouseout\r
305              * The raw mouseout event for the entire grid.\r
306              * @param {Ext.EventObject} e\r
307              */\r
308             'mouseout',\r
309             /**\r
310              * @event keypress\r
311              * The raw keypress event for the entire grid.\r
312              * @param {Ext.EventObject} e\r
313              */\r
314             'keypress',\r
315             /**\r
316              * @event keydown\r
317              * The raw keydown event for the entire grid.\r
318              * @param {Ext.EventObject} e\r
319              */\r
320             'keydown',\r
321 \r
322             // custom events\r
323             /**\r
324              * @event cellmousedown\r
325              * Fires before a cell is clicked\r
326              * @param {Grid} this\r
327              * @param {Number} rowIndex\r
328              * @param {Number} columnIndex\r
329              * @param {Ext.EventObject} e\r
330              */\r
331             'cellmousedown',\r
332             /**\r
333              * @event rowmousedown\r
334              * Fires before a row is clicked\r
335              * @param {Grid} this\r
336              * @param {Number} rowIndex\r
337              * @param {Ext.EventObject} e\r
338              */\r
339             'rowmousedown',\r
340             /**\r
341              * @event headermousedown\r
342              * Fires before a header is clicked\r
343              * @param {Grid} this\r
344              * @param {Number} columnIndex\r
345              * @param {Ext.EventObject} e\r
346              */\r
347             'headermousedown',\r
348 \r
349             /**\r
350              * @event cellclick\r
351              * Fires when a cell is clicked.\r
352              * The data for the cell is drawn from the {@link Ext.data.Record Record}\r
353              * for this row. To access the data in the listener function use the\r
354              * following technique:\r
355              * <pre><code>\r
356 function(grid, rowIndex, columnIndex, e) {\r
357     var record = grid.getStore().getAt(rowIndex);  // Get the Record\r
358     var fieldName = grid.getColumnModel().getDataIndex(columnIndex); // Get field name\r
359     var data = record.get(fieldName);\r
360 }\r
361 </code></pre>\r
362              * @param {Grid} this\r
363              * @param {Number} rowIndex\r
364              * @param {Number} columnIndex\r
365              * @param {Ext.EventObject} e\r
366              */\r
367             'cellclick',\r
368             /**\r
369              * @event celldblclick\r
370              * Fires when a cell is double clicked\r
371              * @param {Grid} this\r
372              * @param {Number} rowIndex\r
373              * @param {Number} columnIndex\r
374              * @param {Ext.EventObject} e\r
375              */\r
376             'celldblclick',\r
377             /**\r
378              * @event rowclick\r
379              * Fires when a row is clicked\r
380              * @param {Grid} this\r
381              * @param {Number} rowIndex\r
382              * @param {Ext.EventObject} e\r
383              */\r
384             'rowclick',\r
385             /**\r
386              * @event rowdblclick\r
387              * Fires when a row is double clicked\r
388              * @param {Grid} this\r
389              * @param {Number} rowIndex\r
390              * @param {Ext.EventObject} e\r
391              */\r
392             'rowdblclick',\r
393             /**\r
394              * @event headerclick\r
395              * Fires when a header is clicked\r
396              * @param {Grid} this\r
397              * @param {Number} columnIndex\r
398              * @param {Ext.EventObject} e\r
399              */\r
400             'headerclick',\r
401             /**\r
402              * @event headerdblclick\r
403              * Fires when a header cell is double clicked\r
404              * @param {Grid} this\r
405              * @param {Number} columnIndex\r
406              * @param {Ext.EventObject} e\r
407              */\r
408             'headerdblclick',\r
409             /**\r
410              * @event rowcontextmenu\r
411              * Fires when a row is right clicked\r
412              * @param {Grid} this\r
413              * @param {Number} rowIndex\r
414              * @param {Ext.EventObject} e\r
415              */\r
416             'rowcontextmenu',\r
417             /**\r
418              * @event cellcontextmenu\r
419              * Fires when a cell is right clicked\r
420              * @param {Grid} this\r
421              * @param {Number} rowIndex\r
422              * @param {Number} cellIndex\r
423              * @param {Ext.EventObject} e\r
424              */\r
425             'cellcontextmenu',\r
426             /**\r
427              * @event headercontextmenu\r
428              * Fires when a header is right clicked\r
429              * @param {Grid} this\r
430              * @param {Number} columnIndex\r
431              * @param {Ext.EventObject} e\r
432              */\r
433             'headercontextmenu',\r
434             /**\r
435              * @event bodyscroll\r
436              * Fires when the body element is scrolled\r
437              * @param {Number} scrollLeft\r
438              * @param {Number} scrollTop\r
439              */\r
440             'bodyscroll',\r
441             /**\r
442              * @event columnresize\r
443              * Fires when the user resizes a column\r
444              * @param {Number} columnIndex\r
445              * @param {Number} newSize\r
446              */\r
447             'columnresize',\r
448             /**\r
449              * @event columnmove\r
450              * Fires when the user moves a column\r
451              * @param {Number} oldIndex\r
452              * @param {Number} newIndex\r
453              */\r
454             'columnmove',\r
455             /**\r
456              * @event sortchange\r
457              * Fires when the grid's store sort changes\r
458              * @param {Grid} this\r
459              * @param {Object} sortInfo An object with the keys field and direction\r
460              */\r
461             'sortchange',\r
462             /**\r
463              * @event reconfigure\r
464              * Fires when the grid is reconfigured with a new store and/or column model.\r
465              * @param {Grid} this\r
466              * @param {Ext.data.Store} store The new store\r
467              * @param {Ext.grid.ColumnModel} colModel The new column model\r
468              */\r
469             'reconfigure'\r
470         );\r
471     },\r
472 \r
473     // private\r
474     onRender : function(ct, position){\r
475         Ext.grid.GridPanel.superclass.onRender.apply(this, arguments);\r
476 \r
477         var c = this.body;\r
478 \r
479         this.el.addClass('x-grid-panel');\r
480 \r
481         var view = this.getView();\r
482         view.init(this);\r
483 \r
484         this.mon(c, {\r
485             mousedown: this.onMouseDown,\r
486             click: this.onClick,\r
487             dblclick: this.onDblClick,\r
488             contextmenu: this.onContextMenu,\r
489             keydown: this.onKeyDown,\r
490             scope: this\r
491         });\r
492 \r
493         this.relayEvents(c, ['mousedown','mouseup','mouseover','mouseout','keypress']);\r
494 \r
495         this.getSelectionModel().init(this);\r
496         this.view.render();\r
497     },\r
498 \r
499     // private\r
500     initEvents : function(){\r
501         Ext.grid.GridPanel.superclass.initEvents.call(this);\r
502 \r
503         if(this.loadMask){\r
504             this.loadMask = new Ext.LoadMask(this.bwrap,\r
505                     Ext.apply({store:this.store}, this.loadMask));\r
506         }\r
507     },\r
508 \r
509     initStateEvents : function(){\r
510         Ext.grid.GridPanel.superclass.initStateEvents.call(this);\r
511         this.mon(this.colModel, 'hiddenchange', this.saveState, this, {delay: 100});\r
512     },\r
513 \r
514     applyState : function(state){\r
515         var cm = this.colModel;\r
516         var cs = state.columns;\r
517         if(cs){\r
518             for(var i = 0, len = cs.length; i < len; i++){\r
519                 var s = cs[i];\r
520                 var c = cm.getColumnById(s.id);\r
521                 if(c){\r
522                     c.hidden = s.hidden;\r
523                     c.width = s.width;\r
524                     var oldIndex = cm.getIndexById(s.id);\r
525                     if(oldIndex != i){\r
526                         cm.moveColumn(oldIndex, i);\r
527                     }\r
528                 }\r
529             }\r
530         }\r
531         if(state.sort && this.store){\r
532             this.store[this.store.remoteSort ? 'setDefaultSort' : 'sort'](state.sort.field, state.sort.direction);\r
533         }\r
534         delete state.columns;\r
535         delete state.sort;\r
536         Ext.grid.GridPanel.superclass.applyState.call(this, state);\r
537     },\r
538 \r
539     getState : function(){\r
540         var o = {columns: []};\r
541         for(var i = 0, c; (c = this.colModel.config[i]); i++){\r
542             o.columns[i] = {\r
543                 id: c.id,\r
544                 width: c.width\r
545             };\r
546             if(c.hidden){\r
547                 o.columns[i].hidden = true;\r
548             }\r
549         }\r
550         if(this.store){\r
551             var ss = this.store.getSortState();\r
552             if(ss){\r
553                 o.sort = ss;\r
554             }\r
555         }\r
556         return o;\r
557     },\r
558 \r
559     // private\r
560     afterRender : function(){\r
561         Ext.grid.GridPanel.superclass.afterRender.call(this);\r
562         this.view.layout();\r
563         if(this.deferRowRender){\r
564             this.view.afterRender.defer(10, this.view);\r
565         }else{\r
566             this.view.afterRender();\r
567         }\r
568         this.viewReady = true;\r
569     },\r
570 \r
571     /**\r
572      * <p>Reconfigures the grid to use a different Store and Column Model\r
573      * and fires the 'reconfigure' event. The View will be bound to the new\r
574      * objects and refreshed.</p>\r
575      * <p>Be aware that upon reconfiguring a GridPanel, certain existing settings <i>may</i> become\r
576      * invalidated. For example the configured {@link #autoExpandColumn} may no longer exist in the\r
577      * new ColumnModel. Also, an existing {@link Ext.PagingToolbar PagingToolbar} will still be bound\r
578      * to the old Store, and will need rebinding. Any {@link #plugins} might also need reconfiguring\r
579      * with the new data.</p>\r
580      * @param {Ext.data.Store} store The new {@link Ext.data.Store} object\r
581      * @param {Ext.grid.ColumnModel} colModel The new {@link Ext.grid.ColumnModel} object\r
582      */\r
583     reconfigure : function(store, colModel){\r
584         if(this.loadMask){\r
585             this.loadMask.destroy();\r
586             this.loadMask = new Ext.LoadMask(this.bwrap,\r
587                     Ext.apply({}, {store:store}, this.initialConfig.loadMask));\r
588         }\r
589         this.view.initData(store, colModel);\r
590         this.store = store;\r
591         this.colModel = colModel;\r
592         if(this.rendered){\r
593             this.view.refresh(true);\r
594         }\r
595         this.fireEvent('reconfigure', this, store, colModel);\r
596     },\r
597 \r
598     // private\r
599     onKeyDown : function(e){\r
600         this.fireEvent('keydown', e);\r
601     },\r
602 \r
603     // private\r
604     onDestroy : function(){\r
605         if(this.rendered){\r
606             var c = this.body;\r
607             c.removeAllListeners();\r
608             c.update('');\r
609             Ext.destroy(this.view, this.loadMask);\r
610         }else if(this.store && this.store.autoDestroy){\r
611             this.store.destroy();\r
612         }\r
613         Ext.destroy(this.colModel, this.selModel);\r
614         this.store = this.selModel = this.colModel = this.view = this.loadMask = null;\r
615         Ext.grid.GridPanel.superclass.onDestroy.call(this);\r
616     },\r
617 \r
618     // private\r
619     processEvent : function(name, e){\r
620         this.fireEvent(name, e);\r
621         var t = e.getTarget();\r
622         var v = this.view;\r
623         var header = v.findHeaderIndex(t);\r
624         if(header !== false){\r
625             this.fireEvent('header' + name, this, header, e);\r
626         }else{\r
627             var row = v.findRowIndex(t);\r
628             var cell = v.findCellIndex(t);\r
629             if(row !== false){\r
630                 this.fireEvent('row' + name, this, row, e);\r
631                 if(cell !== false){\r
632                     this.fireEvent('cell' + name, this, row, cell, e);\r
633                 }\r
634             }\r
635         }\r
636     },\r
637 \r
638     // private\r
639     onClick : function(e){\r
640         this.processEvent('click', e);\r
641     },\r
642 \r
643     // private\r
644     onMouseDown : function(e){\r
645         this.processEvent('mousedown', e);\r
646     },\r
647 \r
648     // private\r
649     onContextMenu : function(e, t){\r
650         this.processEvent('contextmenu', e);\r
651     },\r
652 \r
653     // private\r
654     onDblClick : function(e){\r
655         this.processEvent('dblclick', e);\r
656     },\r
657 \r
658     // private\r
659     walkCells : function(row, col, step, fn, scope){\r
660         var cm = this.colModel, clen = cm.getColumnCount();\r
661         var ds = this.store, rlen = ds.getCount(), first = true;\r
662         if(step < 0){\r
663             if(col < 0){\r
664                 row--;\r
665                 first = false;\r
666             }\r
667             while(row >= 0){\r
668                 if(!first){\r
669                     col = clen-1;\r
670                 }\r
671                 first = false;\r
672                 while(col >= 0){\r
673                     if(fn.call(scope || this, row, col, cm) === true){\r
674                         return [row, col];\r
675                     }\r
676                     col--;\r
677                 }\r
678                 row--;\r
679             }\r
680         } else {\r
681             if(col >= clen){\r
682                 row++;\r
683                 first = false;\r
684             }\r
685             while(row < rlen){\r
686                 if(!first){\r
687                     col = 0;\r
688                 }\r
689                 first = false;\r
690                 while(col < clen){\r
691                     if(fn.call(scope || this, row, col, cm) === true){\r
692                         return [row, col];\r
693                     }\r
694                     col++;\r
695                 }\r
696                 row++;\r
697             }\r
698         }\r
699         return null;\r
700     },\r
701 \r
702     // private\r
703     onResize : function(){\r
704         Ext.grid.GridPanel.superclass.onResize.apply(this, arguments);\r
705         if(this.viewReady){\r
706             this.view.layout();\r
707         }\r
708     },\r
709 \r
710     /**\r
711      * Returns the grid's underlying element.\r
712      * @return {Element} The element\r
713      */\r
714     getGridEl : function(){\r
715         return this.body;\r
716     },\r
717 \r
718     // private for compatibility, overridden by editor grid\r
719     stopEditing : Ext.emptyFn,\r
720 \r
721     /**\r
722      * Returns the grid's selection model configured by the <code>{@link #selModel}</code>\r
723      * configuration option. If no selection model was configured, this will create\r
724      * and return a {@link Ext.grid.RowSelectionModel RowSelectionModel}.\r
725      * @return {SelectionModel}\r
726      */\r
727     getSelectionModel : function(){\r
728         if(!this.selModel){\r
729             this.selModel = new Ext.grid.RowSelectionModel(\r
730                     this.disableSelection ? {selectRow: Ext.emptyFn} : null);\r
731         }\r
732         return this.selModel;\r
733     },\r
734 \r
735     /**\r
736      * Returns the grid's data store.\r
737      * @return {Ext.data.Store} The store\r
738      */\r
739     getStore : function(){\r
740         return this.store;\r
741     },\r
742 \r
743     /**\r
744      * Returns the grid's ColumnModel.\r
745      * @return {Ext.grid.ColumnModel} The column model\r
746      */\r
747     getColumnModel : function(){\r
748         return this.colModel;\r
749     },\r
750 \r
751     /**\r
752      * Returns the grid's GridView object.\r
753      * @return {Ext.grid.GridView} The grid view\r
754      */\r
755     getView : function(){\r
756         if(!this.view){\r
757             this.view = new Ext.grid.GridView(this.viewConfig);\r
758         }\r
759         return this.view;\r
760     },\r
761     /**\r
762      * Called to get grid's drag proxy text, by default returns this.ddText.\r
763      * @return {String} The text\r
764      */\r
765     getDragDropText : function(){\r
766         var count = this.selModel.getCount();\r
767         return String.format(this.ddText, count, count == 1 ? '' : 's');\r
768     }\r
769 \r
770     /** \r
771      * @cfg {String/Number} activeItem \r
772      * @hide \r
773      */\r
774     /** \r
775      * @cfg {Boolean} autoDestroy \r
776      * @hide \r
777      */\r
778     /** \r
779      * @cfg {Object/String/Function} autoLoad \r
780      * @hide \r
781      */\r
782     /** \r
783      * @cfg {Boolean} autoWidth \r
784      * @hide \r
785      */\r
786     /** \r
787      * @cfg {Boolean/Number} bufferResize \r
788      * @hide \r
789      */\r
790     /** \r
791      * @cfg {String} defaultType \r
792      * @hide \r
793      */\r
794     /** \r
795      * @cfg {Object} defaults \r
796      * @hide \r
797      */\r
798     /** \r
799      * @cfg {Boolean} hideBorders \r
800      * @hide \r
801      */\r
802     /** \r
803      * @cfg {Mixed} items \r
804      * @hide \r
805      */\r
806     /** \r
807      * @cfg {String} layout \r
808      * @hide \r
809      */\r
810     /** \r
811      * @cfg {Object} layoutConfig \r
812      * @hide \r
813      */\r
814     /** \r
815      * @cfg {Boolean} monitorResize \r
816      * @hide \r
817      */\r
818     /** \r
819      * @property items \r
820      * @hide \r
821      */\r
822     /** \r
823      * @method add \r
824      * @hide \r
825      */\r
826     /** \r
827      * @method cascade \r
828      * @hide \r
829      */\r
830     /** \r
831      * @method doLayout \r
832      * @hide \r
833      */\r
834     /** \r
835      * @method find \r
836      * @hide \r
837      */\r
838     /** \r
839      * @method findBy \r
840      * @hide \r
841      */\r
842     /** \r
843      * @method findById \r
844      * @hide \r
845      */\r
846     /** \r
847      * @method findByType \r
848      * @hide \r
849      */\r
850     /** \r
851      * @method getComponent \r
852      * @hide \r
853      */\r
854     /** \r
855      * @method getLayout \r
856      * @hide \r
857      */\r
858     /** \r
859      * @method getUpdater \r
860      * @hide \r
861      */\r
862     /** \r
863      * @method insert \r
864      * @hide \r
865      */\r
866     /** \r
867      * @method load \r
868      * @hide \r
869      */\r
870     /** \r
871      * @method remove \r
872      * @hide \r
873      */\r
874     /** \r
875      * @event add \r
876      * @hide \r
877      */\r
878     /** \r
879      * @event afterLayout \r
880      * @hide \r
881      */\r
882     /** \r
883      * @event beforeadd \r
884      * @hide \r
885      */\r
886     /** \r
887      * @event beforeremove \r
888      * @hide \r
889      */\r
890     /** \r
891      * @event remove \r
892      * @hide \r
893      */\r
894 \r
895 \r
896 \r
897     /**\r
898      * @cfg {String} allowDomMove  @hide\r
899      */\r
900     /**\r
901      * @cfg {String} autoEl @hide\r
902      */\r
903     /**\r
904      * @cfg {String} applyTo  @hide\r
905      */\r
906     /**\r
907      * @cfg {String} autoScroll  @hide\r
908      */\r
909     /**\r
910      * @cfg {String} bodyBorder  @hide\r
911      */\r
912     /**\r
913      * @cfg {String} bodyStyle  @hide\r
914      */\r
915     /**\r
916      * @cfg {String} contentEl  @hide\r
917      */\r
918     /**\r
919      * @cfg {String} disabledClass  @hide\r
920      */\r
921     /**\r
922      * @cfg {String} elements  @hide\r
923      */\r
924     /**\r
925      * @cfg {String} html  @hide\r
926      */\r
927     /**\r
928      * @cfg {Boolean} preventBodyReset\r
929      * @hide\r
930      */\r
931     /**\r
932      * @property disabled\r
933      * @hide\r
934      */\r
935     /**\r
936      * @method applyToMarkup\r
937      * @hide\r
938      */\r
939     /**\r
940      * @method enable\r
941      * @hide\r
942      */\r
943     /**\r
944      * @method disable\r
945      * @hide\r
946      */\r
947     /**\r
948      * @method setDisabled\r
949      * @hide\r
950      */\r
951 });\r
952 Ext.reg('grid', Ext.grid.GridPanel);