X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/c930e9176a5a85509c5b0230e2bff5c22a591432..2e847cf21b8ab9d15fa167b315ca5b2fa92638fc:/src/widgets/grid/GridPanel.js diff --git a/src/widgets/grid/GridPanel.js b/src/widgets/grid/GridPanel.js index 9a081324..f74a0cd5 100644 --- a/src/widgets/grid/GridPanel.js +++ b/src/widgets/grid/GridPanel.js @@ -1,6 +1,6 @@ /*! - * Ext JS Library 3.0.0 - * Copyright(c) 2006-2009 Ext JS, LLC + * Ext JS Library 3.1.1 + * Copyright(c) 2006-2010 Ext JS, LLC * licensing@extjs.com * http://www.extjs.com/license */ @@ -22,19 +22,28 @@ *

Example usage:

*

 var grid = new Ext.grid.GridPanel({
-    {@link #store}: new (@link Ext.data.Store}({
+    {@link #store}: new {@link Ext.data.Store}({
         {@link Ext.data.Store#autoDestroy autoDestroy}: true,
         {@link Ext.data.Store#reader reader}: reader,
         {@link Ext.data.Store#data data}: xg.dummyData
     }),
-    {@link #columns}: [
-        {id: 'company', header: 'Company', width: 200, sortable: true, dataIndex: 'company'},
-        {header: 'Price', width: 120, sortable: true, renderer: Ext.util.Format.usMoney, dataIndex: 'price'},
-        {header: 'Change', width: 120, sortable: true, dataIndex: 'change'},
-        {header: '% Change', width: 120, sortable: true, dataIndex: 'pctChange'},
-        // instead of specifying renderer: Ext.util.Format.dateRenderer('m/d/Y') use xtype
-        {header: 'Last Updated', width: 135, sortable: true, dataIndex: 'lastChange', xtype: 'datecolumn', format: 'M d, Y'}
-    ],
+    {@link #colModel}: new {@link Ext.grid.ColumnModel}({
+        {@link Ext.grid.ColumnModel#defaults defaults}: {
+            width: 120,
+            sortable: true
+        },
+        {@link Ext.grid.ColumnModel#columns columns}: [
+            {id: 'company', header: 'Company', width: 200, sortable: true, dataIndex: 'company'},
+            {header: 'Price', renderer: Ext.util.Format.usMoney, dataIndex: 'price'},
+            {header: 'Change', dataIndex: 'change'},
+            {header: '% Change', dataIndex: 'pctChange'},
+            // instead of specifying renderer: Ext.util.Format.dateRenderer('m/d/Y') use xtype
+            {
+                header: 'Last Updated', width: 135, dataIndex: 'lastChange',
+                xtype: 'datecolumn', format: 'M d, Y'
+            }
+        ],
+    }),
     {@link #viewConfig}: {
         {@link Ext.grid.GridView#forceFit forceFit}: true,
 
@@ -140,7 +149,9 @@ Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
      * @cfg {Boolean} enableColumnResize false to turn off column resizing for the whole grid. Defaults to true.
      */
     /**
-     * @cfg {Boolean} enableColumnHide Defaults to true to enable hiding of columns with the header context menu.
+     * @cfg {Boolean} enableColumnHide
+     * Defaults to true to enable {@link Ext.grid.Column#hidden hiding of columns}
+     * with the {@link #enableHdMenu header menu}.
      */
     enableColumnHide : true,
     /**
@@ -206,19 +217,28 @@ Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
      * @cfg {Array} stateEvents
      * An array of events that, when fired, should trigger this component to save its state.
      * Defaults to:

-     * stateEvents: ['columnmove', 'columnresize', 'sortchange']
+     * stateEvents: ['columnmove', 'columnresize', 'sortchange', 'groupchange']
      * 
*

These can be any types of events supported by this component, including browser or * custom events (e.g., ['click', 'customerchange']).

*

See {@link Ext.Component#stateful} for an explanation of saving and restoring * Component state.

*/ - stateEvents : ['columnmove', 'columnresize', 'sortchange'], + stateEvents : ['columnmove', 'columnresize', 'sortchange', 'groupchange'], /** * @cfg {Object} view The {@link Ext.grid.GridView} used by the grid. This can be set * before a call to {@link Ext.Component#render render()}. */ view : null, + + /** + * @cfg {Array} bubbleEvents + *

An array of events that, when fired, should be bubbled to any parent container. + * See {@link Ext.util.Observable#enableBubble}. + * Defaults to []. + */ + bubbleEvents: [], + /** * @cfg {Object} viewConfig A config object that will be applied to the grid's UI view. Any of * the config options available for {@link Ext.grid.GridView} can be specified here. This option @@ -345,6 +365,33 @@ Ext.grid.GridPanel = Ext.extend(Ext.Panel, { * @param {Ext.EventObject} e */ 'headermousedown', + + /** + * @event groupmousedown + * Fires before a group header is clicked. Only applies for grids with a {@link Ext.grid.GroupingView GroupingView}. + * @param {Grid} this + * @param {String} groupField + * @param {String} groupValue + * @param {Ext.EventObject} e + */ + 'groupmousedown', + + /** + * @event rowbodymousedown + * Fires before the row body is clicked. Only applies for grids with {@link Ext.grid.GridView#enableRowBody enableRowBody} configured. + * @param {Grid} this + * @param {Number} rowIndex + * @param {Ext.EventObject} e + */ + 'rowbodymousedown', + + /** + * @event containermousedown + * Fires before the container is clicked. The container consists of any part of the grid body that is not covered by a row. + * @param {Grid} this + * @param {Ext.EventObject} e + */ + 'containermousedown', /** * @event cellclick @@ -406,6 +453,56 @@ function(grid, rowIndex, columnIndex, e) { * @param {Ext.EventObject} e */ 'headerdblclick', + /** + * @event groupclick + * Fires when group header is clicked. Only applies for grids with a {@link Ext.grid.GroupingView GroupingView}. + * @param {Grid} this + * @param {String} groupField + * @param {String} groupValue + * @param {Ext.EventObject} e + */ + 'groupclick', + /** + * @event groupdblclick + * Fires when group header is double clicked. Only applies for grids with a {@link Ext.grid.GroupingView GroupingView}. + * @param {Grid} this + * @param {String} groupField + * @param {String} groupValue + * @param {Ext.EventObject} e + */ + 'groupdblclick', + /** + * @event containerclick + * Fires when the container is clicked. The container consists of any part of the grid body that is not covered by a row. + * @param {Grid} this + * @param {Ext.EventObject} e + */ + 'containerclick', + /** + * @event containerdblclick + * Fires when the container is double clicked. The container consists of any part of the grid body that is not covered by a row. + * @param {Grid} this + * @param {Ext.EventObject} e + */ + 'containerdblclick', + + /** + * @event rowbodyclick + * Fires when the row body is clicked. Only applies for grids with {@link Ext.grid.GridView#enableRowBody enableRowBody} configured. + * @param {Grid} this + * @param {Number} rowIndex + * @param {Ext.EventObject} e + */ + 'rowbodyclick', + /** + * @event rowbodydblclick + * Fires when the row body is double clicked. Only applies for grids with {@link Ext.grid.GridView#enableRowBody enableRowBody} configured. + * @param {Grid} this + * @param {Number} rowIndex + * @param {Ext.EventObject} e + */ + 'rowbodydblclick', + /** * @event rowcontextmenu * Fires when a row is right clicked @@ -431,6 +528,30 @@ function(grid, rowIndex, columnIndex, e) { * @param {Ext.EventObject} e */ 'headercontextmenu', + /** + * @event groupcontextmenu + * Fires when group header is right clicked. Only applies for grids with a {@link Ext.grid.GroupingView GroupingView}. + * @param {Grid} this + * @param {String} groupField + * @param {String} groupValue + * @param {Ext.EventObject} e + */ + 'groupcontextmenu', + /** + * @event containercontextmenu + * Fires when the container is right clicked. The container consists of any part of the grid body that is not covered by a row. + * @param {Grid} this + * @param {Ext.EventObject} e + */ + 'containercontextmenu', + /** + * @event rowbodycontextmenu + * Fires when the row body is right clicked. Only applies for grids with {@link Ext.grid.GridView#enableRowBody enableRowBody} configured. + * @param {Grid} this + * @param {Number} rowIndex + * @param {Ext.EventObject} e + */ + 'rowbodycontextmenu', /** * @event bodyscroll * Fires when the body element is scrolled @@ -459,6 +580,13 @@ function(grid, rowIndex, columnIndex, e) { * @param {Object} sortInfo An object with the keys field and direction */ 'sortchange', + /** + * @event groupchange + * Fires when the grid's grouping changes (only applies for grids with a {@link Ext.grid.GroupingView GroupingView}) + * @param {Grid} this + * @param {String} groupField A string with the grouping field, null if the store is not grouped. + */ + 'groupchange', /** * @event reconfigure * Fires when the grid is reconfigured with a new store and/or column model. @@ -466,7 +594,13 @@ function(grid, rowIndex, columnIndex, e) { * @param {Ext.data.Store} store The new store * @param {Ext.grid.ColumnModel} colModel The new column model */ - 'reconfigure' + 'reconfigure', + /** + * @event viewready + * Fires when the grid view is available (use this for selecting a default row). + * @param {Grid} this + */ + 'viewready' ); }, @@ -474,26 +608,24 @@ function(grid, rowIndex, columnIndex, e) { onRender : function(ct, position){ Ext.grid.GridPanel.superclass.onRender.apply(this, arguments); - var c = this.body; + var c = this.getGridEl(); this.el.addClass('x-grid-panel'); - var view = this.getView(); - view.init(this); - this.mon(c, { + scope: this, mousedown: this.onMouseDown, click: this.onClick, dblclick: this.onDblClick, - contextmenu: this.onContextMenu, - keydown: this.onKeyDown, - scope: this + contextmenu: this.onContextMenu }); - this.relayEvents(c, ['mousedown','mouseup','mouseover','mouseout','keypress']); + this.relayEvents(c, ['mousedown','mouseup','mouseover','mouseout','keypress', 'keydown']); + var view = this.getView(); + view.init(this); + view.render(); this.getSelectionModel().init(this); - this.view.render(); }, // private @@ -512,32 +644,54 @@ function(grid, rowIndex, columnIndex, e) { }, applyState : function(state){ - var cm = this.colModel; - var cs = state.columns; + var cm = this.colModel, + cs = state.columns, + store = this.store, + s, + c, + oldIndex; + if(cs){ for(var i = 0, len = cs.length; i < len; i++){ - var s = cs[i]; - var c = cm.getColumnById(s.id); + s = cs[i]; + c = cm.getColumnById(s.id); if(c){ c.hidden = s.hidden; c.width = s.width; - var oldIndex = cm.getIndexById(s.id); + oldIndex = cm.getIndexById(s.id); if(oldIndex != i){ cm.moveColumn(oldIndex, i); } } } } - if(state.sort && this.store){ - this.store[this.store.remoteSort ? 'setDefaultSort' : 'sort'](state.sort.field, state.sort.direction); + if(store){ + s = state.sort; + if(s){ + store[store.remoteSort ? 'setDefaultSort' : 'sort'](s.field, s.direction); + } + s = state.group; + if(store.groupBy){ + if(s){ + store.groupBy(s); + }else{ + store.clearGrouping(); + } + } + } - delete state.columns; - delete state.sort; - Ext.grid.GridPanel.superclass.applyState.call(this, state); + var o = Ext.apply({}, state); + delete o.columns; + delete o.sort; + Ext.grid.GridPanel.superclass.applyState.call(this, o); }, getState : function(){ - var o = {columns: []}; + var o = {columns: []}, + store = this.store, + ss, + gs; + for(var i = 0, c; (c = this.colModel.config[i]); i++){ o.columns[i] = { id: c.id, @@ -547,11 +701,17 @@ function(grid, rowIndex, columnIndex, e) { o.columns[i].hidden = true; } } - if(this.store){ - var ss = this.store.getSortState(); + if(store){ + ss = store.getSortState(); if(ss){ o.sort = ss; } + if(store.getGroupState){ + gs = store.getGroupState(); + if(gs){ + o.group = gs; + } + } } return o; }, @@ -559,11 +719,13 @@ function(grid, rowIndex, columnIndex, e) { // private afterRender : function(){ Ext.grid.GridPanel.superclass.afterRender.call(this); - this.view.layout(); + var v = this.view; + this.on('bodyresize', v.layout, v); + v.layout(); if(this.deferRowRender){ - this.view.afterRender.defer(10, this.view); + v.afterRender.defer(10, this.view); }else{ - this.view.afterRender(); + v.afterRender(); } this.viewReady = true; }, @@ -581,31 +743,28 @@ function(grid, rowIndex, columnIndex, e) { * @param {Ext.grid.ColumnModel} colModel The new {@link Ext.grid.ColumnModel} object */ reconfigure : function(store, colModel){ - if(this.loadMask){ - this.loadMask.destroy(); - this.loadMask = new Ext.LoadMask(this.bwrap, - Ext.apply({}, {store:store}, this.initialConfig.loadMask)); + var rendered = this.rendered; + if(rendered){ + if(this.loadMask){ + this.loadMask.destroy(); + this.loadMask = new Ext.LoadMask(this.bwrap, + Ext.apply({}, {store:store}, this.initialConfig.loadMask)); + } + } + if(this.view){ + this.view.initData(store, colModel); } - this.view.initData(store, colModel); this.store = store; this.colModel = colModel; - if(this.rendered){ + if(rendered){ this.view.refresh(true); } this.fireEvent('reconfigure', this, store, colModel); }, - // private - onKeyDown : function(e){ - this.fireEvent('keydown', e); - }, - // private onDestroy : function(){ if(this.rendered){ - var c = this.body; - c.removeAllListeners(); - c.update(''); Ext.destroy(this.view, this.loadMask); }else if(this.store && this.store.autoDestroy){ this.store.destroy(); @@ -618,21 +777,31 @@ function(grid, rowIndex, columnIndex, e) { // private processEvent : function(name, e){ this.fireEvent(name, e); - var t = e.getTarget(); - var v = this.view; - var header = v.findHeaderIndex(t); + var t = e.getTarget(), + v = this.view, + header = v.findHeaderIndex(t); + if(header !== false){ this.fireEvent('header' + name, this, header, e); }else{ - var row = v.findRowIndex(t); - var cell = v.findCellIndex(t); + var row = v.findRowIndex(t), + cell, + body; if(row !== false){ this.fireEvent('row' + name, this, row, e); + cell = v.findCellIndex(t); + body = v.findRowBody(t); if(cell !== false){ this.fireEvent('cell' + name, this, row, cell, e); } + if(body){ + this.fireEvent('rowbody' + name, this, row, e); + } + }else{ + this.fireEvent('container' + name, this, e); } } + this.view.processEvent(name, e); }, // private @@ -657,8 +826,11 @@ function(grid, rowIndex, columnIndex, e) { // private walkCells : function(row, col, step, fn, scope){ - var cm = this.colModel, clen = cm.getColumnCount(); - var ds = this.store, rlen = ds.getCount(), first = true; + var cm = this.colModel, + clen = cm.getColumnCount(), + ds = this.store, + rlen = ds.getCount(), + first = true; if(step < 0){ if(col < 0){ row--; @@ -876,7 +1048,7 @@ function(grid, rowIndex, columnIndex, e) { * @hide */ /** - * @event afterLayout + * @event afterlayout * @hide */ /**