PageRenderTime 72ms CodeModel.GetById 13ms app.highlight 50ms RepoModel.GetById 1ms app.codeStats 1ms

/hippo/src/main/webapp/ext/src/widgets/grid/GridPanel.js

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