2 * Ext JS Library 2.2.1
\r
3 * Copyright(c) 2006-2009, Ext JS, LLC.
\r
4 * licensing@extjs.com
\r
6 * http://extjs.com/license
\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
14 * <pre><code>var grid = new Ext.grid.GridPanel({
\r
15 store: new Ext.data.Store({
\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
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
33 return 'price-fall';
\r
35 return 'price-rise';
\r
39 sm: new Ext.grid.RowSelectionModel({singleSelect:true}),
\r
43 title:'Framed with Checkbox Selection and Horizontal Scrolling',
\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
56 * @param {Object} config The config object
\r
58 Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
\r
60 * @cfg {Ext.data.Store} store The {@link Ext.data.Store} the grid should use as its data source (required).
\r
63 * @cfg {Object} cm Shorthand for {@link #colModel}.
\r
66 * @cfg {Object} colModel The {@link Ext.grid.ColumnModel} to use when rendering the grid (required).
\r
69 * @cfg {Object} sm Shorthand for {@link #selModel}.
\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
76 * @cfg {Array} columns An array of columns to auto create a ColumnModel
\r
79 * @cfg {Number} maxHeight Sets the maximum height of the grid - ignored if autoHeight is not on.
\r
82 * @cfg {Boolean} disableSelection True to disable selections in the grid (defaults to false). - ignored if a SelectionModel is specified
\r
85 * @cfg {Boolean} enableColumnMove False to turn off column reordering via drag drop (defaults to true).
\r
88 * @cfg {Boolean} enableColumnResize False to turn off column resizing for the whole grid (defaults to true).
\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
96 * @cfg {Boolean} hideHeaders True to hide the grid's header (defaults to false).
\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
104 ddText : "{0} selected row{1}",
\r
106 * @cfg {Number} minColumnWidth The minimum width a column can be resized to. Defaults to 25.
\r
108 minColumnWidth : 25,
\r
110 * @cfg {Boolean} trackMouseOver True to highlight rows when the mouse is over. Default is true.
\r
112 trackMouseOver : true,
\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
123 enableDragDrop : false,
\r
125 * @cfg {Boolean} enableColumnMove True to enable drag and drop reorder of columns.
\r
127 enableColumnMove : true,
\r
129 * @cfg {Boolean} enableColumnHide True to enable hiding of columns with the header context menu.
\r
131 enableColumnHide : true,
\r
133 * @cfg {Boolean} enableHdMenu True to enable the drop down button for menu in the headers.
\r
135 enableHdMenu : true,
\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
143 stripeRows : false,
\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
147 autoExpandColumn : false,
\r
149 * @cfg {Number} autoExpandMin The minimum width the autoExpandColumn can have (if enabled).
\r
152 autoExpandMin : 50,
\r
154 * @cfg {Number} autoExpandMax The maximum width the autoExpandColumn can have (if enabled). Defaults to 1000.
\r
156 autoExpandMax : 1000,
\r
158 * @cfg {Object} view The {@link Ext.grid.GridView} used by the grid. This can be set before a call to render().
\r
162 * @cfg {Object} loadMask An {@link Ext.LoadMask} config or true to mask the grid while loading (defaults to false).
\r
167 * @cfg {Boolean} deferRowRender True to enable deferred row rendering. Default is true.
\r
169 deferRowRender : true,
\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
182 stateEvents: ["columnmove", "columnresize", "sortchange"],
\r
185 initComponent : function(){
\r
186 Ext.grid.GridPanel.superclass.initComponent.call(this);
\r
188 // override any provided value since it isn't valid
\r
189 this.autoScroll = false;
\r
190 this.autoWidth = false;
\r
192 if(Ext.isArray(this.columns)){
\r
193 this.colModel = new Ext.grid.ColumnModel(this.columns);
\r
194 delete this.columns;
\r
197 // check and correct shorthanded configs
\r
199 this.store = this.ds;
\r
203 this.colModel = this.cm;
\r
207 this.selModel = this.sm;
\r
210 this.store = Ext.StoreMgr.lookup(this.store);
\r
216 * The raw click event for the entire grid.
\r
217 * @param {Ext.EventObject} e
\r
222 * The raw dblclick event for the entire grid.
\r
223 * @param {Ext.EventObject} e
\r
227 * @event contextmenu
\r
228 * The raw contextmenu event for the entire grid.
\r
229 * @param {Ext.EventObject} e
\r
234 * The raw mousedown event for the entire grid.
\r
235 * @param {Ext.EventObject} e
\r
240 * The raw mouseup event for the entire grid.
\r
241 * @param {Ext.EventObject} e
\r
246 * The raw mouseover event for the entire grid.
\r
247 * @param {Ext.EventObject} e
\r
252 * The raw mouseout event for the entire grid.
\r
253 * @param {Ext.EventObject} e
\r
258 * The raw keypress event for the entire grid.
\r
259 * @param {Ext.EventObject} e
\r
264 * The raw keydown event for the entire grid.
\r
265 * @param {Ext.EventObject} e
\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
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
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
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
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
309 * @param {Grid} this
\r
310 * @param {Number} rowIndex
\r
311 * @param {Number} columnIndex
\r
312 * @param {Ext.EventObject} e
\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
326 * Fires when a row is clicked
\r
327 * @param {Grid} this
\r
328 * @param {Number} rowIndex
\r
329 * @param {Ext.EventObject} e
\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
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
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
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
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
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
380 "headercontextmenu",
\r
382 * @event bodyscroll
\r
383 * Fires when the body element is scrolled
\r
384 * @param {Number} scrollLeft
\r
385 * @param {Number} scrollTop
\r
389 * @event columnresize
\r
390 * Fires when the user resizes a column
\r
391 * @param {Number} columnIndex
\r
392 * @param {Number} newSize
\r
396 * @event columnmove
\r
397 * Fires when the user moves a column
\r
398 * @param {Number} oldIndex
\r
399 * @param {Number} newIndex
\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
413 onRender : function(ct, position){
\r
414 Ext.grid.GridPanel.superclass.onRender.apply(this, arguments);
\r
418 this.el.addClass('x-grid-panel');
\r
420 var view = this.getView();
\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
429 this.relayEvents(c, ["mousedown","mouseup","mouseover","mouseout","keypress"]);
\r
431 this.getSelectionModel().init(this);
\r
432 this.view.render();
\r
436 initEvents : function(){
\r
437 Ext.grid.GridPanel.superclass.initEvents.call(this);
\r
440 this.loadMask = new Ext.LoadMask(this.bwrap,
\r
441 Ext.apply({store:this.store}, this.loadMask));
\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
450 applyState : function(state){
\r
451 var cm = this.colModel;
\r
452 var cs = state.columns;
\r
454 for(var i = 0, len = cs.length; i < len; i++){
\r
456 var c = cm.getColumnById(s.id);
\r
458 c.hidden = s.hidden;
\r
460 var oldIndex = cm.getIndexById(s.id);
\r
462 cm.moveColumn(oldIndex, i);
\r
468 this.store[this.store.remoteSort ? 'setDefaultSort' : 'sort'](state.sort.field, state.sort.direction);
\r
472 getState : function(){
\r
473 var o = {columns: []};
\r
474 for(var i = 0, c; c = this.colModel.config[i]; i++){
\r
480 o.columns[i].hidden = true;
\r
483 var ss = this.store.getSortState();
\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
497 this.view.afterRender();
\r
499 this.viewReady = true;
\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
513 reconfigure : function(store, colModel){
\r
515 this.loadMask.destroy();
\r
516 this.loadMask = new Ext.LoadMask(this.bwrap,
\r
517 Ext.apply({store:store}, this.initialConfig.loadMask));
\r
519 this.view.bind(store, colModel);
\r
520 this.store = store;
\r
521 this.colModel = colModel;
\r
523 this.view.refresh(true);
\r
528 onKeyDown : function(e){
\r
529 this.fireEvent("keydown", e);
\r
533 onDestroy : function(){
\r
536 this.loadMask.destroy();
\r
539 c.removeAllListeners();
\r
540 this.view.destroy();
\r
543 this.colModel.purgeListeners();
\r
544 Ext.grid.GridPanel.superclass.onDestroy.call(this);
\r
548 processEvent : function(name, e){
\r
549 this.fireEvent(name, e);
\r
550 var t = e.getTarget();
\r
552 var header = v.findHeaderIndex(t);
\r
553 if(header !== false){
\r
554 this.fireEvent("header" + name, this, header, e);
\r
556 var row = v.findRowIndex(t);
\r
557 var cell = v.findCellIndex(t);
\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
568 onClick : function(e){
\r
569 this.processEvent("click", e);
\r
573 onMouseDown : function(e){
\r
574 this.processEvent("mousedown", e);
\r
578 onContextMenu : function(e, t){
\r
579 this.processEvent("contextmenu", e);
\r
583 onDblClick : function(e){
\r
584 this.processEvent("dblclick", e);
\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
602 if(fn.call(scope || this, row, col, cm) === true){
\r
620 if(fn.call(scope || this, row, col, cm) === true){
\r
632 getSelections : function(){
\r
633 return this.selModel.getSelections();
\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
645 * Returns the grid's underlying element.
\r
646 * @return {Element} The element
\r
648 getGridEl : function(){
\r
652 // private for compatibility, overridden by editor grid
\r
653 stopEditing : Ext.emptyFn,
\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
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
666 return this.selModel;
\r
670 * Returns the grid's data store.
\r
671 * @return {Ext.data.Store} The store
\r
673 getStore : function(){
\r
678 * Returns the grid's ColumnModel.
\r
679 * @return {Ext.grid.ColumnModel} The column model
\r
681 getColumnModel : function(){
\r
682 return this.colModel;
\r
686 * Returns the grid's GridView object.
\r
687 * @return {Ext.grid.GridView} The grid view
\r
689 getView : function(){
\r
691 this.view = new Ext.grid.GridView(this.viewConfig);
\r
696 * Called to get grid's drag proxy text, by default returns this.ddText.
\r
697 * @return {String} The text
\r
699 getDragDropText : function(){
\r
700 var count = this.selModel.getCount();
\r
701 return String.format(this.ddText, count, count == 1 ? '' : 's');
\r
705 * @cfg {String/Number} activeItem
\r
709 * @cfg {Boolean} autoDestroy
\r
713 * @cfg {Object/String/Function} autoLoad
\r
717 * @cfg {Boolean} autoWidth
\r
721 * @cfg {Boolean/Number} bufferResize
\r
725 * @cfg {String} defaultType
\r
729 * @cfg {Object} defaults
\r
733 * @cfg {Boolean} hideBorders
\r
737 * @cfg {Mixed} items
\r
741 * @cfg {String} layout
\r
745 * @cfg {Object} layoutConfig
\r
749 * @cfg {Boolean} monitorResize
\r
765 * @method doLayout
\r
777 * @method findById
\r
781 * @method findByType
\r
785 * @method getComponent
\r
789 * @method getLayout
\r
793 * @method getUpdater
\r
813 * @event afterLayout
\r
817 * @event beforeadd
\r
821 * @event beforeremove
\r
832 * @cfg {String} allowDomMove @hide
\r
835 * @cfg {String} autoEl @hide
\r
838 * @cfg {String} applyTo @hide
\r
841 * @cfg {String} autoScroll @hide
\r
844 * @cfg {String} bodyBorder @hide
\r
847 * @cfg {String} bodyStyle @hide
\r
850 * @cfg {String} contentEl @hide
\r
853 * @cfg {String} disabledClass @hide
\r
856 * @cfg {String} elements @hide
\r
859 * @cfg {String} html @hide
\r
862 * @property disabled
\r
866 * @method applyToMarkup
\r
878 * @method setDisabled
\r
882 Ext.reg('grid', Ext.grid.GridPanel);