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