<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>The source code</title> <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" /> <script type="text/javascript" src="../resources/prettify/prettify.js"></script> <style type="text/css"> .highlight { display: block; background-color: #ddd; } </style> <script type="text/javascript"> function highlight() { document.getElementById(location.hash.replace(/#/, "")).className = "highlight"; } </script> </head> <body onload="prettyPrint(); highlight();"> <pre class="prettyprint lang-js"><span id='Ext-panel-Table'>/** </span> * @author Nicolas Ferrero * * TablePanel is the basis of both {@link Ext.tree.Panel TreePanel} and {@link Ext.grid.Panel GridPanel}. * * TablePanel aggregates: * * - a Selection Model * - a View * - a Store * - Scrollers * - Ext.grid.header.Container */ Ext.define('Ext.panel.Table', { extend: 'Ext.panel.Panel', alias: 'widget.tablepanel', uses: [ 'Ext.selection.RowModel', 'Ext.selection.CellModel', 'Ext.selection.CheckboxModel', 'Ext.grid.PagingScroller', 'Ext.grid.header.Container', 'Ext.grid.Lockable' ], extraBaseCls: Ext.baseCSSPrefix + 'grid', extraBodyCls: Ext.baseCSSPrefix + 'grid-body', layout: 'fit', <span id='Ext-panel-Table-property-hasView'> /** </span> * @property {Boolean} hasView * True to indicate that a view has been injected into the panel. */ hasView: false, // each panel should dictate what viewType and selType to use <span id='Ext-panel-Table-cfg-viewType'> /** </span> * @cfg {String} viewType * An xtype of view to use. This is automatically set to 'gridview' by {@link Ext.grid.Panel Grid} * and to 'treeview' by {@link Ext.tree.Panel Tree}. * @protected */ viewType: null, <span id='Ext-panel-Table-cfg-viewConfig'> /** </span> * @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.view.Table} can be specified here. This option is ignored if {@link #view} is specified. */ <span id='Ext-panel-Table-cfg-view'> /** </span> * @cfg {Ext.view.Table} view * The {@link Ext.view.Table} used by the grid. Use {@link #viewConfig} to just supply some config options to * view (instead of creating an entire View instance). */ <span id='Ext-panel-Table-cfg-selType'> /** </span> * @cfg {String} selType * An xtype of selection model to use. Defaults to 'rowmodel'. This is used to create selection model if just * a config object or nothing at all given in {@link #selModel} config. */ selType: 'rowmodel', <span id='Ext-panel-Table-cfg-selModel'> /** </span> * @cfg {Ext.selection.Model/Object} selModel * A {@link Ext.selection.Model selection model} instance or config object. In latter case the {@link #selType} * config option determines to which type of selection model this config is applied. */ <span id='Ext-panel-Table-cfg-multiSelect'> /** </span> * @cfg {Boolean} [multiSelect=false] * True to enable 'MULTI' selection mode on selection model. * @deprecated 4.1.1 Use {@link Ext.selection.Model#mode} 'MULTI' instead. */ <span id='Ext-panel-Table-cfg-simpleSelect'> /** </span> * @cfg {Boolean} [simpleSelect=false] * True to enable 'SIMPLE' selection mode on selection model. * @deprecated 4.1.1 Use {@link Ext.selection.Model#mode} 'SIMPLE' instead. */ <span id='Ext-panel-Table-cfg-store'> /** </span> * @cfg {Ext.data.Store} store (required) * The {@link Ext.data.Store Store} the grid should use as its data source. */ <span id='Ext-panel-Table-cfg-scroll'> /** </span> * @cfg {String/Boolean} scroll * Scrollers configuration. Valid values are 'both', 'horizontal' or 'vertical'. * True implies 'both'. False implies 'none'. */ scroll: true, <span id='Ext-panel-Table-cfg-columns'> /** </span> * @cfg {Ext.grid.column.Column[]/Object} columns * An array of {@link Ext.grid.column.Column column} definition objects which define all columns that appear in this * grid. Each column definition provides the header text for the column, and a definition of where the data for that * column comes from. * * This can also be a configuration object for a {Ext.grid.header.Container HeaderContainer} which may override * certain default configurations if necessary. For example, the special layout may be overridden to use a simpler * layout, or one can set default values shared by all columns: * * columns: { * items: [ * { * text: "Column A" * dataIndex: "field_A" * },{ * text: "Column B", * dataIndex: "field_B" * }, * ... * ], * defaults: { * flex: 1 * } * } */ <span id='Ext-panel-Table-cfg-forceFit'> /** </span> * @cfg {Boolean} forceFit * Ttrue to force the columns to fit into the available width. Headers are first sized according to configuration, * whether that be a specific width, or flex. Then they are all proportionally changed in width so that the entire * content width is used. For more accurate control, it is more optimal to specify a flex setting on the columns * that are to be stretched & explicit widths on columns that are not. */ <span id='Ext-panel-Table-cfg-features'> /** </span> * @cfg {Ext.grid.feature.Feature[]} features * An array of grid Features to be added to this grid. See {@link Ext.grid.feature.Feature} for usage. */ <span id='Ext-panel-Table-cfg-hideHeaders'> /** </span> * @cfg {Boolean} [hideHeaders=false] * True to hide column headers. */ <span id='Ext-panel-Table-cfg-deferRowRender'> /** </span> * @cfg {Boolean} deferRowRender * Defaults to true to enable deferred row rendering. * * This allows the View to execute a refresh quickly, with the expensive update of the row structure deferred so * that layouts with GridPanels appear, and lay out more quickly. */ <span id='Ext-panel-Table-cfg-verticalScroller'> /** </span> * @cfg {Object} verticalScroller * A config object to be used when configuring the {@link Ext.grid.PagingScroller scroll monitor} to control * refreshing of data in an "infinite grid". * * Configurations of this object allow fine tuning of data caching which can improve performance and usability * of the infinite grid. */ deferRowRender: true, <span id='Ext-panel-Table-cfg-sortableColumns'> /** </span> * @cfg {Boolean} sortableColumns * False to disable column sorting via clicking the header and via the Sorting menu items. */ sortableColumns: true, <span id='Ext-panel-Table-cfg-enableLocking'> /** </span> * @cfg {Boolean} [enableLocking=false] * True to enable locking support for this grid. Alternatively, locking will also be automatically * enabled if any of the columns in the column configuration contain the locked config option. */ enableLocking: false, // private property used to determine where to go down to find views // this is here to support locking. scrollerOwner: true, <span id='Ext-panel-Table-cfg-enableColumnMove'> /** </span> * @cfg {Boolean} [enableColumnMove=true] * False to disable column dragging within this grid. */ enableColumnMove: true, <span id='Ext-panel-Table-cfg-sealedColumns'> /** </span> * @cfg {Boolean} [sealedColumns=false] * True to constrain column dragging so that a column cannot be dragged in or out of it's * current group. Only relevant while {@link #enableColumnMove} is enabled. */ sealedColumns: false, <span id='Ext-panel-Table-cfg-enableColumnResize'> /** </span> * @cfg {Boolean} [enableColumnResize=true] * False to disable column resizing within this grid. */ enableColumnResize: true, <span id='Ext-panel-Table-cfg-enableColumnHide'> /** </span> * @cfg {Boolean} [enableColumnHide=true] * False to disable column hiding within this grid. */ enableColumnHide: true, <span id='Ext-panel-Table-cfg-columnLines'> /** </span> * @cfg {Boolean} columnLines Adds column line styling */ <span id='Ext-panel-Table-cfg-rowLines'> /** </span> * @cfg {Boolean} [rowLines=true] Adds row line styling */ rowLines: true, <span id='Ext-panel-Table-cfg-disableSelection'> /** </span> * @cfg {Boolean} [disableSelection=false] * True to disable selection model. */ <span id='Ext-panel-Table-cfg-emptyText'> /** </span> * @cfg {String} emptyText Default text (html tags are accepted) to display in the Panel body when the Store * is empty. When specified, and the Store is empty, the text will be rendered inside a DIV with the CSS class "x-grid-empty". */ <span id='Ext-panel-Table-cfg-allowDeselect'> /** </span> * @cfg {Boolean} [allowDeselect=false] * True to allow deselecting a record. This config is forwarded to {@link Ext.selection.Model#allowDeselect}. */ <span id='Ext-panel-Table-property-optimizedColumnMove'> /** </span> * @property {Boolean} optimizedColumnMove * If you are writing a grid plugin or a {Ext.grid.feature.Feature Feature} which creates a column-based structure which * needs a view refresh when columns are moved, then set this property in the grid. * * An example is the built in {@link Ext.grid.feature.AbstractSummary Summary} Feature. This creates summary rows, and the * summary columns must be in the same order as the data columns. This plugin sets the `optimizedColumnMove` to `false. */ initComponent: function() { //<debug> if (!this.viewType) { Ext.Error.raise("You must specify a viewType config."); } if (this.headers) { Ext.Error.raise("The headers config is not supported. Please specify columns instead."); } //</debug> var me = this, scroll = me.scroll, vertical = false, horizontal = false, headerCtCfg = me.columns || me.colModel, view, border = me.border, i, len; if (me.columnLines) { me.addCls(Ext.baseCSSPrefix + 'grid-with-col-lines'); } if (me.rowLines) { me.addCls(Ext.baseCSSPrefix + 'grid-with-row-lines'); } // Look up the configured Store. If none configured, use the fieldless, empty Store defined in Ext.data.Store. me.store = Ext.data.StoreManager.lookup(me.store || 'ext-empty-store'); //<debug> if (!headerCtCfg) { Ext.Error.raise("A column configuration must be specified"); } //</debug> // The columns/colModel config may be either a fully instantiated HeaderContainer, or an array of Column definitions, or a config object of a HeaderContainer // Either way, we extract a columns property referencing an array of Column definitions. if (headerCtCfg instanceof Ext.grid.header.Container) { me.headerCt = headerCtCfg; me.headerCt.border = border; me.columns = me.headerCt.items.items; } else { if (Ext.isArray(headerCtCfg)) { headerCtCfg = { items: headerCtCfg, border: border }; } Ext.apply(headerCtCfg, { forceFit: me.forceFit, sortable: me.sortableColumns, enableColumnMove: me.enableColumnMove, enableColumnResize: me.enableColumnResize, enableColumnHide: me.enableColumnHide, border: border, sealed: me.sealedColumns }); me.columns = headerCtCfg.items; // If any of the Column objects contain a locked property, and are not processed, this is a lockable TablePanel, a // special view will be injected by the Ext.grid.Lockable mixin, so no processing of . if (me.enableLocking || Ext.ComponentQuery.query('{locked !== undefined}{processed != true}', me.columns).length) { me.self.mixin('lockable', Ext.grid.Lockable); me.injectLockable(); } } me.scrollTask = new Ext.util.DelayedTask(me.syncHorizontalScroll, me); me.addEvents( // documented on GridPanel 'reconfigure', <span id='Ext-panel-Table-event-viewready'> /** </span> * @event viewready * Fires when the grid view is available (use this for selecting a default row). * @param {Ext.panel.Table} this */ 'viewready' ); me.bodyCls = me.bodyCls || ''; me.bodyCls += (' ' + me.extraBodyCls); me.cls = me.cls || ''; me.cls += (' ' + me.extraBaseCls); // autoScroll is not a valid configuration delete me.autoScroll; // If this TablePanel is lockable (Either configured lockable, or any of the defined columns has a 'locked' property) // than a special lockable view containing 2 side-by-side grids will have been injected so we do not need to set up any UI. if (!me.hasView) { // If we were not configured with a ready-made headerCt (either by direct config with a headerCt property, or by passing // a HeaderContainer instance as the 'columns' property, then go ahead and create one from the config object created above. if (!me.headerCt) { me.headerCt = new Ext.grid.header.Container(headerCtCfg); } // Extract the array of Column objects me.columns = me.headerCt.items.items; // If the Store is paging blocks of the dataset in, then it can only be sorted remotely. if (me.store.buffered && !me.store.remoteSort) { for (i = 0, len = me.columns.length; i < len; i++) { me.columns[i].sortable = false; } } if (me.hideHeaders) { me.headerCt.height = 0; me.headerCt.addCls(Ext.baseCSSPrefix + 'grid-header-ct-hidden'); me.addCls(Ext.baseCSSPrefix + 'grid-header-hidden'); // IE Quirks Mode fix // If hidden configuration option was used, several layout calculations will be bypassed. if (Ext.isIEQuirks) { me.headerCt.style = { display: 'none' }; } } // turn both on. if (scroll === true || scroll === 'both') { vertical = horizontal = true; } else if (scroll === 'horizontal') { horizontal = true; } else if (scroll === 'vertical') { vertical = true; } me.relayHeaderCtEvents(me.headerCt); me.features = me.features || []; if (!Ext.isArray(me.features)) { me.features = [me.features]; } me.dockedItems = [].concat(me.dockedItems || []); me.dockedItems.unshift(me.headerCt); me.viewConfig = me.viewConfig || {}; // Buffered scrolling must preserve scroll on refresh if (me.store && me.store.buffered) { me.viewConfig.preserveScrollOnRefresh = true; } else if (me.invalidateScrollerOnRefresh !== undefined) { me.viewConfig.preserveScrollOnRefresh = !me.invalidateScrollerOnRefresh; } // AbstractDataView will look up a Store configured as an object // getView converts viewConfig into a View instance view = me.getView(); me.items = [view]; me.hasView = true; if (vertical) { // If the Store is buffered, create a PagingScroller to monitor the View's scroll progress, // load the Store's prefetch buffer when it detects we are nearing an edge. if (me.store.buffered) { me.verticalScroller = new Ext.grid.PagingScroller(Ext.apply({ panel: me, store: me.store, view: me.view }, me.verticalScroller)); } } if (horizontal) { // Add a listener to synchronize the horizontal scroll position of the headers // with the table view's element... Unless we are not showing headers! if (!me.hideHeaders) { view.on({ scroll: { fn: me.onHorizontalScroll, element: 'el', scope: me } }); } } me.mon(view.store, { load: me.onStoreLoad, scope: me }); me.mon(view, { viewready: me.onViewReady, refresh: me.onRestoreHorzScroll, scope: me }); } // Relay events from the View whether it be a LockingView, or a regular GridView this.relayEvents(me.view, [ <span id='Ext-panel-Table-event-beforeitemmousedown'> /** </span> * @event beforeitemmousedown * @inheritdoc Ext.view.View#beforeitemmousedown */ 'beforeitemmousedown', <span id='Ext-panel-Table-event-beforeitemmouseup'> /** </span> * @event beforeitemmouseup * @inheritdoc Ext.view.View#beforeitemmouseup */ 'beforeitemmouseup', <span id='Ext-panel-Table-event-beforeitemmouseenter'> /** </span> * @event beforeitemmouseenter * @inheritdoc Ext.view.View#beforeitemmouseenter */ 'beforeitemmouseenter', <span id='Ext-panel-Table-event-beforeitemmouseleave'> /** </span> * @event beforeitemmouseleave * @inheritdoc Ext.view.View#beforeitemmouseleave */ 'beforeitemmouseleave', <span id='Ext-panel-Table-event-beforeitemclick'> /** </span> * @event beforeitemclick * @inheritdoc Ext.view.View#beforeitemclick */ 'beforeitemclick', <span id='Ext-panel-Table-event-beforeitemdblclick'> /** </span> * @event beforeitemdblclick * @inheritdoc Ext.view.View#beforeitemdblclick */ 'beforeitemdblclick', <span id='Ext-panel-Table-event-beforeitemcontextmenu'> /** </span> * @event beforeitemcontextmenu * @inheritdoc Ext.view.View#beforeitemcontextmenu */ 'beforeitemcontextmenu', <span id='Ext-panel-Table-event-itemmousedown'> /** </span> * @event itemmousedown * @inheritdoc Ext.view.View#itemmousedown */ 'itemmousedown', <span id='Ext-panel-Table-event-itemmouseup'> /** </span> * @event itemmouseup * @inheritdoc Ext.view.View#itemmouseup */ 'itemmouseup', <span id='Ext-panel-Table-event-itemmouseenter'> /** </span> * @event itemmouseenter * @inheritdoc Ext.view.View#itemmouseenter */ 'itemmouseenter', <span id='Ext-panel-Table-event-itemmouseleave'> /** </span> * @event itemmouseleave * @inheritdoc Ext.view.View#itemmouseleave */ 'itemmouseleave', <span id='Ext-panel-Table-event-itemclick'> /** </span> * @event itemclick * @inheritdoc Ext.view.View#itemclick */ 'itemclick', <span id='Ext-panel-Table-event-itemdblclick'> /** </span> * @event itemdblclick * @inheritdoc Ext.view.View#itemdblclick */ 'itemdblclick', <span id='Ext-panel-Table-event-itemcontextmenu'> /** </span> * @event itemcontextmenu * @inheritdoc Ext.view.View#itemcontextmenu */ 'itemcontextmenu', <span id='Ext-panel-Table-event-beforecontainermousedown'> /** </span> * @event beforecontainermousedown * @inheritdoc Ext.view.View#beforecontainermousedown */ 'beforecontainermousedown', <span id='Ext-panel-Table-event-beforecontainermouseup'> /** </span> * @event beforecontainermouseup * @inheritdoc Ext.view.View#beforecontainermouseup */ 'beforecontainermouseup', <span id='Ext-panel-Table-event-beforecontainermouseover'> /** </span> * @event beforecontainermouseover * @inheritdoc Ext.view.View#beforecontainermouseover */ 'beforecontainermouseover', <span id='Ext-panel-Table-event-beforecontainermouseout'> /** </span> * @event beforecontainermouseout * @inheritdoc Ext.view.View#beforecontainermouseout */ 'beforecontainermouseout', <span id='Ext-panel-Table-event-beforecontainerclick'> /** </span> * @event beforecontainerclick * @inheritdoc Ext.view.View#beforecontainerclick */ 'beforecontainerclick', <span id='Ext-panel-Table-event-beforecontainerdblclick'> /** </span> * @event beforecontainerdblclick * @inheritdoc Ext.view.View#beforecontainerdblclick */ 'beforecontainerdblclick', <span id='Ext-panel-Table-event-beforecontainercontextmenu'> /** </span> * @event beforecontainercontextmenu * @inheritdoc Ext.view.View#beforecontainercontextmenu */ 'beforecontainercontextmenu', <span id='Ext-panel-Table-event-containermouseup'> /** </span> * @event containermouseup * @inheritdoc Ext.view.View#containermouseup */ 'containermouseup', <span id='Ext-panel-Table-event-containermouseover'> /** </span> * @event containermouseover * @inheritdoc Ext.view.View#containermouseover */ 'containermouseover', <span id='Ext-panel-Table-event-containermouseout'> /** </span> * @event containermouseout * @inheritdoc Ext.view.View#containermouseout */ 'containermouseout', <span id='Ext-panel-Table-event-containerclick'> /** </span> * @event containerclick * @inheritdoc Ext.view.View#containerclick */ 'containerclick', <span id='Ext-panel-Table-event-containerdblclick'> /** </span> * @event containerdblclick * @inheritdoc Ext.view.View#containerdblclick */ 'containerdblclick', <span id='Ext-panel-Table-event-containercontextmenu'> /** </span> * @event containercontextmenu * @inheritdoc Ext.view.View#containercontextmenu */ 'containercontextmenu', <span id='Ext-panel-Table-event-selectionchange'> /** </span> * @event selectionchange * @inheritdoc Ext.selection.Model#selectionchange */ 'selectionchange', <span id='Ext-panel-Table-event-beforeselect'> /** </span> * @event beforeselect * @inheritdoc Ext.selection.RowModel#beforeselect */ 'beforeselect', <span id='Ext-panel-Table-event-select'> /** </span> * @event select * @inheritdoc Ext.selection.RowModel#select */ 'select', <span id='Ext-panel-Table-event-beforedeselect'> /** </span> * @event beforedeselect * @inheritdoc Ext.selection.RowModel#beforedeselect */ 'beforedeselect', <span id='Ext-panel-Table-event-deselect'> /** </span> * @event deselect * @inheritdoc Ext.selection.RowModel#deselect */ 'deselect' ]); me.callParent(arguments); me.addStateEvents(['columnresize', 'columnmove', 'columnhide', 'columnshow', 'sortchange']); if (me.headerCt) { me.headerCt.on('afterlayout', me.onRestoreHorzScroll, me); } }, relayHeaderCtEvents: function (headerCt) { this.relayEvents(headerCt, [ <span id='Ext-panel-Table-event-columnresize'> /** </span> * @event columnresize * @inheritdoc Ext.grid.header.Container#columnresize */ 'columnresize', <span id='Ext-panel-Table-event-columnmove'> /** </span> * @event columnmove * @inheritdoc Ext.grid.header.Container#columnmove */ 'columnmove', <span id='Ext-panel-Table-event-columnhide'> /** </span> * @event columnhide * @inheritdoc Ext.grid.header.Container#columnhide */ 'columnhide', <span id='Ext-panel-Table-event-columnshow'> /** </span> * @event columnshow * @inheritdoc Ext.grid.header.Container#columnshow */ 'columnshow', <span id='Ext-panel-Table-event-sortchange'> /** </span> * @event sortchange * @inheritdoc Ext.grid.header.Container#sortchange */ 'sortchange' ]); }, getState: function(){ var me = this, state = me.callParent(), sorter = me.store.sorters.first(); state = me.addPropertyToState(state, 'columns', (me.headerCt || me).getColumnsState()); if (sorter) { state = me.addPropertyToState(state, 'sort', { property: sorter.property, direction: sorter.direction, root: sorter.root }); } return state; }, applyState: function(state) { var me = this, sorter = state.sort, store = me.store, columns = state.columns; delete state.columns; // Ensure superclass has applied *its* state. // AbstractComponent saves dimensions (and anchor/flex) plus collapsed state. me.callParent(arguments); if (columns) { (me.headerCt || me).applyColumnsState(columns); } if (sorter) { if (store.remoteSort) { // Pass false to prevent a sort from occurring store.sort({ property: sorter.property, direction: sorter.direction, root: sorter.root }, null, false); } else { store.sort(sorter.property, sorter.direction); } } }, <span id='Ext-panel-Table-method-getStore'> /** </span> * Returns the store associated with this Panel. * @return {Ext.data.Store} The store */ getStore: function(){ return this.store; }, <span id='Ext-panel-Table-method-getView'> /** </span> * Gets the view for this panel. * @return {Ext.view.Table} */ getView: function() { var me = this, sm; if (!me.view) { sm = me.getSelectionModel(); me.view = Ext.widget(Ext.apply({}, me.viewConfig, { // Features need a reference to the grid, so configure a reference into the View grid: me, deferInitialRefresh: me.deferRowRender !== false, scroll: me.scroll, xtype: me.viewType, store: me.store, headerCt: me.headerCt, selModel: sm, features: me.features, panel: me, emptyText : me.emptyText ? '<div class="' + Ext.baseCSSPrefix + 'grid-empty">' + me.emptyText + '</div>' : '' })); // TableView's custom component layout, Ext.view.TableLayout requires a reference to the headerCt because it depends on the headerCt doing its work. me.view.getComponentLayout().headerCt = me.headerCt; me.mon(me.view, { uievent: me.processEvent, scope: me }); sm.view = me.view; me.headerCt.view = me.view; me.relayEvents(me.view, [ <span id='Ext-panel-Table-event-cellclick'> /** </span> * @event cellclick * Fired when table cell is clicked. * @param {Ext.view.Table} this * @param {HTMLElement} td The TD element that was clicked. * @param {Number} cellIndex * @param {Ext.data.Model} record * @param {HTMLElement} tr The TR element that was clicked. * @param {Number} rowIndex * @param {Ext.EventObject} e */ 'cellclick', <span id='Ext-panel-Table-event-celldblclick'> /** </span> * @event celldblclick * Fired when table cell is double clicked. * @param {Ext.view.Table} this * @param {HTMLElement} td The TD element that was clicked. * @param {Number} cellIndex * @param {Ext.data.Model} record * @param {HTMLElement} tr The TR element that was clicked. * @param {Number} rowIndex * @param {Ext.EventObject} e */ 'celldblclick' ]); } return me.view; }, <span id='Ext-panel-Table-method-setAutoScroll'> /** </span> * @private * autoScroll is never valid for all classes which extend TablePanel. */ setAutoScroll: Ext.emptyFn, <span id='Ext-panel-Table-method-processEvent'> /** </span> * @private * Processes UI events from the view. Propagates them to whatever internal Components need to process them. * @param {String} type Event type, eg 'click' * @param {Ext.view.Table} view TableView Component * @param {HTMLElement} cell Cell HtmlElement the event took place within * @param {Number} recordIndex Index of the associated Store Model (-1 if none) * @param {Number} cellIndex Cell index within the row * @param {Ext.EventObject} e Original event */ processEvent: function(type, view, cell, recordIndex, cellIndex, e) { var me = this, header; if (cellIndex !== -1) { header = me.headerCt.getGridColumns()[cellIndex]; return header.processEvent.apply(header, arguments); } }, <span id='Ext-panel-Table-method-determineScrollbars'> /** </span> * This method is obsolete in 4.1. The closest equivalent in * 4.1 is {@link #doLayout}, but it is also possible that no * layout is needed. * @deprecated 4.1 */ determineScrollbars: function () { //<debug> Ext.log.warn('Obsolete'); //</debug> }, <span id='Ext-panel-Table-method-invalidateScroller'> /** </span> * This method is obsolete in 4.1. The closest equivalent in 4.1 is * {@link Ext.AbstractComponent#updateLayout}, but it is also possible that no layout * is needed. * @deprecated 4.1 */ invalidateScroller: function () { //<debug> Ext.log.warn('Obsolete'); //</debug> }, scrollByDeltaY: function(yDelta, animate) { this.getView().scrollBy(0, yDelta, animate); }, scrollByDeltaX: function(xDelta, animate) { this.getView().scrollBy(xDelta, 0, animate); }, afterCollapse: function() { var me = this; me.saveScrollPos(); me.saveScrollPos(); me.callParent(arguments); }, afterExpand: function() { var me = this; me.callParent(arguments); me.restoreScrollPos(); me.restoreScrollPos(); }, saveScrollPos: Ext.emptyFn, restoreScrollPos: Ext.emptyFn, onHeaderResize: function(){ this.delayScroll(); }, // Update the view when a header moves onHeaderMove: function(headerCt, header, colsToMove, fromIdx, toIdx) { var me = this; // If there are Features or Plugins which create DOM which must match column order, they set the optimizedColumnMove flag to false. // In this case we must refresh the view on column move. if (me.optimizedColumnMove === false) { me.view.refresh(); } // Simplest case for default DOM structure is just to swap the columns round in the view. else { me.view.moveColumn(fromIdx, toIdx, colsToMove); } me.delayScroll(); }, // Section onHeaderHide is invoked after view. onHeaderHide: function(headerCt, header) { this.delayScroll(); }, onHeaderShow: function(headerCt, header) { this.delayScroll(); }, delayScroll: function(){ var target = this.getScrollTarget().el; if (target) { this.scrollTask.delay(10, null, null, [target.dom.scrollLeft]); } }, <span id='Ext-panel-Table-method-onViewReady'> /** </span> * @private * Fires the TablePanel's viewready event when the view declares that its internal DOM is ready */ onViewReady: function() { this.fireEvent('viewready', this); }, <span id='Ext-panel-Table-method-onRestoreHorzScroll'> /** </span> * @private * Tracks when things happen to the view and preserves the horizontal scroll position. */ onRestoreHorzScroll: function() { var left = this.scrollLeftPos; if (left) { // We need to restore the body scroll position here this.syncHorizontalScroll(left, true); } }, getScrollerOwner: function() { var rootCmp = this; if (!this.scrollerOwner) { rootCmp = this.up('[scrollerOwner]'); } return rootCmp; }, <span id='Ext-panel-Table-method-getLhsMarker'> /** </span> * Gets left hand side marker for header resizing. * @private */ getLhsMarker: function() { var me = this; return me.lhsMarker || (me.lhsMarker = Ext.DomHelper.append(me.el, { cls: Ext.baseCSSPrefix + 'grid-resize-marker' }, true)); }, <span id='Ext-panel-Table-method-getRhsMarker'> /** </span> * Gets right hand side marker for header resizing. * @private */ getRhsMarker: function() { var me = this; return me.rhsMarker || (me.rhsMarker = Ext.DomHelper.append(me.el, { cls: Ext.baseCSSPrefix + 'grid-resize-marker' }, true)); }, <span id='Ext-panel-Table-method-getSelectionModel'> /** </span> * Returns the selection model being used and creates it via the configuration if it has not been created already. * @return {Ext.selection.Model} selModel */ getSelectionModel: function(){ if (!this.selModel) { this.selModel = {}; } var mode = 'SINGLE', type; if (this.simpleSelect) { mode = 'SIMPLE'; } else if (this.multiSelect) { mode = 'MULTI'; } Ext.applyIf(this.selModel, { allowDeselect: this.allowDeselect, mode: mode }); if (!this.selModel.events) { type = this.selModel.selType || this.selType; this.selModel = Ext.create('selection.' + type, this.selModel); } if (!this.selModel.hasRelaySetup) { this.relayEvents(this.selModel, [ 'selectionchange', 'beforeselect', 'beforedeselect', 'select', 'deselect' ]); this.selModel.hasRelaySetup = true; } // lock the selection model if user // has disabled selection if (this.disableSelection) { this.selModel.locked = true; } return this.selModel; }, getScrollTarget: function(){ var owner = this.getScrollerOwner(), items = owner.query('tableview'); return items[1] || items[0]; }, onHorizontalScroll: function(event, target) { this.syncHorizontalScroll(target.scrollLeft); }, syncHorizontalScroll: function(left, setBody) { var me = this, scrollTarget; setBody = setBody === true; // Only set the horizontal scroll if we've changed position, // so that we don't set this on vertical scrolls if (me.rendered && (setBody || left !== me.scrollLeftPos)) { // Only set the body position if we're reacting to a refresh, otherwise // we just need to set the header. if (setBody) { scrollTarget = me.getScrollTarget(); scrollTarget.el.dom.scrollLeft = left; } me.headerCt.el.dom.scrollLeft = left; me.scrollLeftPos = left; } }, // template method meant to be overriden onStoreLoad: Ext.emptyFn, getEditorParent: function() { return this.body; }, bindStore: function(store) { var me = this; me.store = store; me.getView().bindStore(store); }, beforeDestroy: function(){ Ext.destroy(this.verticalScroller); this.callParent(); }, // documented on GridPanel reconfigure: function(store, columns) { var me = this, headerCt = me.headerCt; if (me.lockable) { me.reconfigureLockable(store, columns); } else { Ext.suspendLayouts(); if (columns) { // new columns, delete scroll pos delete me.scrollLeftPos; headerCt.removeAll(); headerCt.add(columns); } if (store) { store = Ext.StoreManager.lookup(store); me.bindStore(store); } else { me.getView().refresh(); } headerCt.setSortState(); Ext.resumeLayouts(true); } me.fireEvent('reconfigure', me, store, columns); } }); </pre> </body> </html>