<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>The source code</title>
- <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
- <script type="text/javascript" src="../prettify/prettify.js"></script>
+ <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>
</head>
<body onload="prettyPrint(); highlight();">
- <pre class="prettyprint lang-js"><span id='Ext-layout-container-Table'>/**
-</span> * @class Ext.layout.container.Table
- * @extends Ext.layout.container.Auto
- * <p>This layout allows you to easily render content into an HTML table. The total number of columns can be
- * specified, and rowspan and colspan can be used to create complex layouts within the table.
- * This class is intended to be extended or created via the <code>layout: {type: 'table'}</code>
- * {@link Ext.container.Container#layout} config, and should generally not need to be created directly via the new keyword.</p>
- * <p>Note that when creating a layout via config, the layout-specific config properties must be passed in via
- * the {@link Ext.container.Container#layout} object which will then be applied internally to the layout. In the
- * case of TableLayout, the only valid layout config properties are {@link #columns} and {@link #tableAttrs}.
- * However, the items added to a TableLayout can supply the following table-specific config properties:</p>
- * <ul>
- * <li><b>rowspan</b> Applied to the table cell containing the item.</li>
- * <li><b>colspan</b> Applied to the table cell containing the item.</li>
- * <li><b>cellId</b> An id applied to the table cell containing the item.</li>
- * <li><b>cellCls</b> A CSS class name added to the table cell containing the item.</li>
- * </ul>
- * <p>The basic concept of building up a TableLayout is conceptually very similar to building up a standard
- * HTML table. You simply add each panel (or "cell") that you want to include along with any span attributes
- * specified as the special config properties of rowspan and colspan which work exactly like their HTML counterparts.
- * Rather than explicitly creating and nesting rows and columns as you would in HTML, you simply specify the
- * total column count in the layoutConfig and start adding panels in their natural order from left to right,
- * top to bottom. The layout will automatically figure out, based on the column count, rowspans and colspans,
- * how to position each panel within the table. Just like with HTML tables, your rowspans and colspans must add
- * up correctly in your overall layout or you'll end up with missing and/or extra cells! Example usage:</p>
- * {@img Ext.layout.container.Table/Ext.layout.container.Table.png Ext.layout.container.Table container layout}
- * <pre><code>
-// This code will generate a layout table that is 3 columns by 2 rows
-// with some spanning included. The basic layout will be:
-// +--------+-----------------+
-// | A | B |
-// | |--------+--------|
-// | | C | D |
-// +--------+--------+--------+
- Ext.create('Ext.panel.Panel', {
- title: 'Table Layout',
- width: 300,
- height: 150,
- layout: {
- type: 'table',
- // The total column count must be specified here
- columns: 3
- },
- defaults: {
- // applied to each contained panel
- bodyStyle:'padding:20px'
- },
- items: [{
- html: 'Cell A content',
- rowspan: 2
- },{
- html: 'Cell B content',
- colspan: 2
- },{
- html: 'Cell C content',
- cellCls: 'highlight'
- },{
- html: 'Cell D content'
- }],
- renderTo: Ext.getBody()
- });
-</code></pre>
+ <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',
-Ext.define('Ext.layout.container.Table', {
+ alias: 'widget.tablepanel',
- /* Begin Definitions */
+ uses: [
+ 'Ext.selection.RowModel',
+ 'Ext.grid.Scroller',
+ 'Ext.grid.header.Container',
+ 'Ext.grid.Lockable'
+ ],
- alias: ['layout.table'],
- extend: 'Ext.layout.container.Auto',
- alternateClassName: 'Ext.layout.TableLayout',
+ extraBaseCls: Ext.baseCSSPrefix + 'grid',
+ extraBodyCls: Ext.baseCSSPrefix + 'grid-body',
- /* End Definitions */
+ 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,
-<span id='Ext-layout-container-Table-cfg-columns'> /**
-</span> * @cfg {Number} columns
- * The total number of columns to create in the table for this layout. If not specified, all Components added to
- * this layout will be rendered into a single row using one column per Component.
+ // 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}.
*/
+ viewType: null,
- // private
- monitorResize:false,
+<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.
+ */
- type: 'table',
+<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).
+ */
- // Table layout is a self-sizing layout. When an item of for example, a dock layout, the Panel must expand to accommodate
- // a table layout. See in particular AbstractDock::onLayout for use of this flag.
- autoSize: true,
+<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',
- clearEl: true, // Base class will not create it if already truthy. Not needed in tables.
+<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.
+ */
- targetCls: Ext.baseCSSPrefix + 'table-layout-ct',
- tableCls: Ext.baseCSSPrefix + 'table-layout',
- cellCls: Ext.baseCSSPrefix + 'table-layout-cell',
+<span id='Ext-panel-Table-cfg-multiSelect'> /**
+</span> * @cfg {Boolean} multiSelect
+ * True to enable 'MULTI' selection mode on selection model. See {@link Ext.selection.Model#mode}.
+ */
-<span id='Ext-layout-container-Table-cfg-tableAttrs'> /**
-</span> * @cfg {Object} tableAttrs
- * <p>An object containing properties which are added to the {@link Ext.core.DomHelper DomHelper} specification
- * used to create the layout's <tt>&lt;table&gt;</tt> element. Example:</p><pre><code>
-{
- xtype: 'panel',
- layout: {
- type: 'table',
- columns: 3,
- tableAttrs: {
- style: {
- width: '100%'
- }
- }
- }
-}</code></pre>
+<span id='Ext-panel-Table-cfg-simpleSelect'> /**
+</span> * @cfg {Boolean} simpleSelect
+ * True to enable 'SIMPLE' selection mode on selection model. See {@link Ext.selection.Model#mode}.
*/
- tableAttrs:null,
-<span id='Ext-layout-container-Table-cfg-trAttrs'> /**
-</span> * @cfg {Object} trAttrs
- * <p>An object containing properties which are added to the {@link Ext.core.DomHelper DomHelper} specification
- * used to create the layout's <tt>&lt;tr&gt;</tt> elements.
+<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-layout-container-Table-cfg-tdAttrs'> /**
-</span> * @cfg {Object} tdAttrs
- * <p>An object containing properties which are added to the {@link Ext.core.DomHelper DomHelper} specification
- * used to create the layout's <tt>&lt;td&gt;</tt> elements.
+<span id='Ext-panel-Table-cfg-scrollDelta'> /**
+</span> * @cfg {Number} scrollDelta
+ * Number of pixels to scroll when scrolling with mousewheel.
*/
+ scrollDelta: 40,
-<span id='Ext-layout-container-Table-method-renderItems'> /**
-</span> * @private
- * Iterates over all passed items, ensuring they are rendered in a cell in the proper
- * location in the table structure.
+<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'.
*/
- renderItems: function(items) {
- var tbody = this.getTable().tBodies[0],
- rows = tbody.rows,
- i = 0,
- len = items.length,
- cells, curCell, rowIdx, cellIdx, item, trEl, tdEl, itemCt;
+ scroll: true,
- // Calculate the correct cell structure for the current items
- cells = this.calculateCells(items);
+<span id='Ext-panel-Table-cfg-columns'> /**
+</span> * @cfg {Ext.grid.column.Column[]} 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.
+ */
- // Loop over each cell and compare to the current cells in the table, inserting/
- // removing/moving cells as needed, and making sure each item is rendered into
- // the correct cell.
- for (; i < len; i++) {
- curCell = cells[i];
- rowIdx = curCell.rowIdx;
- cellIdx = curCell.cellIdx;
- item = items[i];
-
- // If no row present, create and insert one
- trEl = rows[rowIdx];
- if (!trEl) {
- trEl = tbody.insertRow(rowIdx);
- if (this.trAttrs) {
- trEl.set(this.trAttrs);
+<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.
+ */
+
+<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.
+ */
+
+ 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,
+
+ verticalScrollDock: 'right',
+ verticalScrollerType: 'gridscroller',
+
+ horizontalScrollerPresentCls: Ext.baseCSSPrefix + 'horizontal-scroller-present',
+ verticalScrollerPresentCls: Ext.baseCSSPrefix + 'vertical-scroller-present',
+
+ // private property used to determine where to go down to find views
+ // this is here to support locking.
+ scrollerOwner: true,
+
+ invalidateScrollerOnRefresh: true,
+
+<span id='Ext-panel-Table-cfg-enableColumnMove'> /**
+</span> * @cfg {Boolean} enableColumnMove
+ * False to disable column dragging within this grid.
+ */
+ enableColumnMove: true,
+
+<span id='Ext-panel-Table-cfg-enableColumnResize'> /**
+</span> * @cfg {Boolean} enableColumnResize
+ * False to disable column resizing within this grid.
+ */
+ enableColumnResize: true,
+
+<span id='Ext-panel-Table-cfg-enableColumnHide'> /**
+</span> * @cfg {Boolean} enableColumnHide
+ * False to disable column hiding within this grid.
+ */
+ enableColumnHide: true,
+
+ 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,
+ i = 0,
+ view,
+ border = me.border;
+
+ if (me.hideHeaders) {
+ border = false;
+ }
+
+ // 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');
+
+ // 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
+ });
+ 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.addEvents(
+<span id='Ext-panel-Table-event-reconfigure'> /**
+</span> * @event reconfigure
+ * Fires after a reconfigure.
+ * @param {Ext.panel.Table} this
+ */
+ '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',
+<span id='Ext-panel-Table-event-scrollerhide'> /**
+</span> * @event scrollerhide
+ * Fires when a scroller is hidden.
+ * @param {Ext.grid.Scroller} scroller
+ * @param {String} orientation Orientation, can be 'vertical' or 'horizontal'
+ */
+ 'scrollerhide',
+<span id='Ext-panel-Table-event-scrollershow'> /**
+</span> * @event scrollershow
+ * Fires when a scroller is shown.
+ * @param {Ext.grid.Scroller} scroller
+ * @param {String} orientation Orientation, can be 'vertical' or 'horizontal'
+ */
+ 'scrollershow'
+ );
+
+ 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 = Ext.create('Ext.grid.header.Container', headerCtCfg);
+ }
+
+ // Extract the array of Column objects
+ me.columns = me.headerCt.items.items;
+
+ if (me.hideHeaders) {
+ me.headerCt.height = 0;
+ me.headerCt.border = false;
+ 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'
+ };
}
}
- // If no cell present, create and insert one
- itemCt = tdEl = Ext.get(trEl.cells[cellIdx] || trEl.insertCell(cellIdx));
- if (this.needsDivWrap()) { //create wrapper div if needed - see docs below
- itemCt = tdEl.first() || tdEl.createChild({tag: 'div'});
- itemCt.setWidth(null);
+ // turn both on.
+ if (scroll === true || scroll === 'both') {
+ vertical = horizontal = true;
+ } else if (scroll === 'horizontal') {
+ horizontal = true;
+ } else if (scroll === 'vertical') {
+ vertical = true;
+ // All other values become 'none' or false.
+ } else {
+ me.headerCt.availableSpaceOffset = 0;
}
- // Render or move the component into the cell
- if (!item.rendered) {
- this.renderItem(item, itemCt, 0);
+ if (vertical) {
+ me.verticalScroller = Ext.ComponentManager.create(me.initVerticalScroller());
+ me.mon(me.verticalScroller, {
+ bodyscroll: me.onVerticalScroll,
+ scope: me
+ });
}
- else if (!this.isValidParent(item, itemCt, 0)) {
- this.moveItem(item, itemCt, 0);
+
+ if (horizontal) {
+ me.horizontalScroller = Ext.ComponentManager.create(me.initHorizontalScroller());
+ me.mon(me.horizontalScroller, {
+ bodyscroll: me.onHorizontalScroll,
+ scope: me
+ });
}
- // Set the cell properties
- if (this.tdAttrs) {
- tdEl.set(this.tdAttrs);
+ me.headerCt.on('resize', me.onHeaderResize, me);
+ me.relayHeaderCtEvents(me.headerCt);
+ me.features = me.features || [];
+ if (!Ext.isArray(me.features)) {
+ me.features = [me.features];
}
- tdEl.set({
- colSpan: item.colspan || 1,
- rowSpan: item.rowspan || 1,
- id: item.cellId || '',
- cls: this.cellCls + ' ' + (item.cellCls || '')
+ me.dockedItems = me.dockedItems || [];
+ me.dockedItems.unshift(me.headerCt);
+ me.viewConfig = me.viewConfig || {};
+ me.viewConfig.invalidateScrollerOnRefresh = me.invalidateScrollerOnRefresh;
+
+ // AbstractDataView will look up a Store configured as an object
+ // getView converts viewConfig into a View instance
+ view = me.getView();
+
+ view.on({
+ afterrender: function () {
+ // hijack the view el's scroll method
+ view.el.scroll = Ext.Function.bind(me.elScroll, me);
+ // We use to listen to document.body wheel events, but that's a
+ // little much. We scope just to the view now.
+ me.mon(view.el, {
+ mousewheel: me.onMouseWheel,
+ scope: me
+ });
+ },
+ single: true
});
+ me.items = [view];
+ me.hasView = true;
- // If at the end of a row, remove any extra cells
- if (!cells[i + 1] || cells[i + 1].rowIdx !== rowIdx) {
- cellIdx++;
- while (trEl.cells[cellIdx]) {
- trEl.deleteCell(cellIdx);
- }
- }
+ me.mon(view.store, {
+ load: me.onStoreLoad,
+ scope: me
+ });
+ me.mon(view, {
+ viewReady: me.onViewReady,
+ resize: me.onViewResize,
+ refresh: {
+ fn: me.onViewRefresh,
+ scope: me,
+ buffer: 50
+ },
+ scope: me
+ });
+ this.relayEvents(view, [
+<span id='Ext-panel-Table-event-beforeitemmousedown'> /**
+</span> * @event beforeitemmousedown
+ * @alias Ext.view.View#beforeitemmousedown
+ */
+ 'beforeitemmousedown',
+<span id='Ext-panel-Table-event-beforeitemmouseup'> /**
+</span> * @event beforeitemmouseup
+ * @alias Ext.view.View#beforeitemmouseup
+ */
+ 'beforeitemmouseup',
+<span id='Ext-panel-Table-event-beforeitemmouseenter'> /**
+</span> * @event beforeitemmouseenter
+ * @alias Ext.view.View#beforeitemmouseenter
+ */
+ 'beforeitemmouseenter',
+<span id='Ext-panel-Table-event-beforeitemmouseleave'> /**
+</span> * @event beforeitemmouseleave
+ * @alias Ext.view.View#beforeitemmouseleave
+ */
+ 'beforeitemmouseleave',
+<span id='Ext-panel-Table-event-beforeitemclick'> /**
+</span> * @event beforeitemclick
+ * @alias Ext.view.View#beforeitemclick
+ */
+ 'beforeitemclick',
+<span id='Ext-panel-Table-event-beforeitemdblclick'> /**
+</span> * @event beforeitemdblclick
+ * @alias Ext.view.View#beforeitemdblclick
+ */
+ 'beforeitemdblclick',
+<span id='Ext-panel-Table-event-beforeitemcontextmenu'> /**
+</span> * @event beforeitemcontextmenu
+ * @alias Ext.view.View#beforeitemcontextmenu
+ */
+ 'beforeitemcontextmenu',
+<span id='Ext-panel-Table-event-itemmousedown'> /**
+</span> * @event itemmousedown
+ * @alias Ext.view.View#itemmousedown
+ */
+ 'itemmousedown',
+<span id='Ext-panel-Table-event-itemmouseup'> /**
+</span> * @event itemmouseup
+ * @alias Ext.view.View#itemmouseup
+ */
+ 'itemmouseup',
+<span id='Ext-panel-Table-event-itemmouseenter'> /**
+</span> * @event itemmouseenter
+ * @alias Ext.view.View#itemmouseenter
+ */
+ 'itemmouseenter',
+<span id='Ext-panel-Table-event-itemmouseleave'> /**
+</span> * @event itemmouseleave
+ * @alias Ext.view.View#itemmouseleave
+ */
+ 'itemmouseleave',
+<span id='Ext-panel-Table-event-itemclick'> /**
+</span> * @event itemclick
+ * @alias Ext.view.View#itemclick
+ */
+ 'itemclick',
+<span id='Ext-panel-Table-event-itemdblclick'> /**
+</span> * @event itemdblclick
+ * @alias Ext.view.View#itemdblclick
+ */
+ 'itemdblclick',
+<span id='Ext-panel-Table-event-itemcontextmenu'> /**
+</span> * @event itemcontextmenu
+ * @alias Ext.view.View#itemcontextmenu
+ */
+ 'itemcontextmenu',
+<span id='Ext-panel-Table-event-beforecontainermousedown'> /**
+</span> * @event beforecontainermousedown
+ * @alias Ext.view.View#beforecontainermousedown
+ */
+ 'beforecontainermousedown',
+<span id='Ext-panel-Table-event-beforecontainermouseup'> /**
+</span> * @event beforecontainermouseup
+ * @alias Ext.view.View#beforecontainermouseup
+ */
+ 'beforecontainermouseup',
+<span id='Ext-panel-Table-event-beforecontainermouseover'> /**
+</span> * @event beforecontainermouseover
+ * @alias Ext.view.View#beforecontainermouseover
+ */
+ 'beforecontainermouseover',
+<span id='Ext-panel-Table-event-beforecontainermouseout'> /**
+</span> * @event beforecontainermouseout
+ * @alias Ext.view.View#beforecontainermouseout
+ */
+ 'beforecontainermouseout',
+<span id='Ext-panel-Table-event-beforecontainerclick'> /**
+</span> * @event beforecontainerclick
+ * @alias Ext.view.View#beforecontainerclick
+ */
+ 'beforecontainerclick',
+<span id='Ext-panel-Table-event-beforecontainerdblclick'> /**
+</span> * @event beforecontainerdblclick
+ * @alias Ext.view.View#beforecontainerdblclick
+ */
+ 'beforecontainerdblclick',
+<span id='Ext-panel-Table-event-beforecontainercontextmenu'> /**
+</span> * @event beforecontainercontextmenu
+ * @alias Ext.view.View#beforecontainercontextmenu
+ */
+ 'beforecontainercontextmenu',
+<span id='Ext-panel-Table-event-containermouseup'> /**
+</span> * @event containermouseup
+ * @alias Ext.view.View#containermouseup
+ */
+ 'containermouseup',
+<span id='Ext-panel-Table-event-containermouseover'> /**
+</span> * @event containermouseover
+ * @alias Ext.view.View#containermouseover
+ */
+ 'containermouseover',
+<span id='Ext-panel-Table-event-containermouseout'> /**
+</span> * @event containermouseout
+ * @alias Ext.view.View#containermouseout
+ */
+ 'containermouseout',
+<span id='Ext-panel-Table-event-containerclick'> /**
+</span> * @event containerclick
+ * @alias Ext.view.View#containerclick
+ */
+ 'containerclick',
+<span id='Ext-panel-Table-event-containerdblclick'> /**
+</span> * @event containerdblclick
+ * @alias Ext.view.View#containerdblclick
+ */
+ 'containerdblclick',
+<span id='Ext-panel-Table-event-containercontextmenu'> /**
+</span> * @event containercontextmenu
+ * @alias Ext.view.View#containercontextmenu
+ */
+ 'containercontextmenu',
+<span id='Ext-panel-Table-event-selectionchange'> /**
+</span> * @event selectionchange
+ * @alias Ext.selection.Model#selectionchange
+ */
+ 'selectionchange',
+<span id='Ext-panel-Table-event-beforeselect'> /**
+</span> * @event beforeselect
+ * @alias Ext.selection.RowModel#beforeselect
+ */
+ 'beforeselect',
+<span id='Ext-panel-Table-event-select'> /**
+</span> * @event select
+ * @alias Ext.selection.RowModel#select
+ */
+ 'select',
+<span id='Ext-panel-Table-event-beforedeselect'> /**
+</span> * @event beforedeselect
+ * @alias Ext.selection.RowModel#beforedeselect
+ */
+ 'beforedeselect',
+<span id='Ext-panel-Table-event-deselect'> /**
+</span> * @event deselect
+ * @alias Ext.selection.RowModel#deselect
+ */
+ 'deselect'
+ ]);
}
- // Delete any extra rows
- rowIdx++;
- while (tbody.rows[rowIdx]) {
- tbody.deleteRow(rowIdx);
+ me.callParent(arguments);
+ },
+
+ onRender: function(){
+ var vScroll = this.verticalScroller,
+ hScroll = this.horizontalScroller;
+
+ if (vScroll) {
+ vScroll.ensureDimension();
}
+ if (hScroll) {
+ hScroll.ensureDimension();
+ }
+ this.callParent(arguments);
},
- afterLayout: function() {
+ // state management
+ initStateEvents: function(){
+ var events = this.stateEvents;
+ // push on stateEvents if they don't exist
+ Ext.each(['columnresize', 'columnmove', 'columnhide', 'columnshow', 'sortchange'], function(event){
+ if (Ext.Array.indexOf(events, event)) {
+ events.push(event);
+ }
+ });
this.callParent();
+ },
+
+<span id='Ext-panel-Table-method-initHorizontalScroller'> /**
+</span> * Returns the horizontal scroller config.
+ */
+ initHorizontalScroller: function () {
+ var me = this,
+ ret = {
+ xtype: 'gridscroller',
+ dock: 'bottom',
+ section: me,
+ store: me.store
+ };
+
+ return ret;
+ },
+
+<span id='Ext-panel-Table-method-initVerticalScroller'> /**
+</span> * Returns the vertical scroller config.
+ */
+ initVerticalScroller: function () {
+ var me = this,
+ ret = me.verticalScroller || {};
+
+ Ext.applyIf(ret, {
+ xtype: me.verticalScrollerType,
+ dock: me.verticalScrollDock,
+ store: me.store
+ });
+
+ return ret;
+ },
+
+ relayHeaderCtEvents: function (headerCt) {
+ this.relayEvents(headerCt, [
+<span id='Ext-panel-Table-event-columnresize'> /**
+</span> * @event columnresize
+ * @alias Ext.grid.header.Container#columnresize
+ */
+ 'columnresize',
+<span id='Ext-panel-Table-event-columnmove'> /**
+</span> * @event columnmove
+ * @alias Ext.grid.header.Container#columnmove
+ */
+ 'columnmove',
+<span id='Ext-panel-Table-event-columnhide'> /**
+</span> * @event columnhide
+ * @alias Ext.grid.header.Container#columnhide
+ */
+ 'columnhide',
+<span id='Ext-panel-Table-event-columnshow'> /**
+</span> * @event columnshow
+ * @alias Ext.grid.header.Container#columnshow
+ */
+ 'columnshow',
+<span id='Ext-panel-Table-event-sortchange'> /**
+</span> * @event sortchange
+ * @alias Ext.grid.header.Container#sortchange
+ */
+ 'sortchange'
+ ]);
+ },
+
+ getState: function(){
+ var me = this,
+ state = me.callParent(),
+ sorter = me.store.sorters.first();
- if (this.needsDivWrap()) {
- // set wrapper div width to match layed out item - see docs below
- Ext.Array.forEach(this.getLayoutItems(), function(item) {
- Ext.fly(item.el.dom.parentNode).setWidth(item.getWidth());
+ state.columns = (me.headerCt || me).getColumnsState();
+
+ if (sorter) {
+ state.sort = {
+ property: sorter.property,
+ direction: sorter.direction
+ };
+ }
+
+ 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) {
+ store.sorters.add(Ext.create('Ext.util.Sorter', {
+ property: sorter.property,
+ direction: sorter.direction
+ }));
+ }
+ 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 = me.createComponent(Ext.apply({}, me.viewConfig, {
+ deferInitialRefresh: me.deferRowRender,
+ xtype: me.viewType,
+ store: me.store,
+ headerCt: me.headerCt,
+ selModel: sm,
+ features: me.features,
+ panel: me
+ }));
+ me.mon(me.view, {
+ uievent: me.processEvent,
+ scope: me
});
+ sm.view = me.view;
+ me.headerCt.view = me.view;
+ me.relayEvents(me.view, ['cellclick', 'celldblclick']);
}
+ return me.view;
},
-<span id='Ext-layout-container-Table-method-calculateCells'> /**
+<span id='Ext-panel-Table-property-setAutoScroll'> /**
</span> * @private
- * Determine the row and cell indexes for each component, taking into consideration
- * the number of columns and each item's configured colspan/rowspan values.
- * @param {Array} items The layout components
- * @return {Array} List of row and cell indexes for each of the components
- */
- calculateCells: function(items) {
- var cells = [],
- rowIdx = 0,
- colIdx = 0,
- cellIdx = 0,
- totalCols = this.columns || Infinity,
- rowspans = [], //rolling list of active rowspans for each column
- i = 0, j,
- len = items.length,
- item;
+ * @override
+ * autoScroll is never valid for all classes which extend TablePanel.
+ */
+ setAutoScroll: Ext.emptyFn,
- for (; i < len; i++) {
- item = items[i];
-
- // Find the first available row/col slot not taken up by a spanning cell
- while (colIdx >= totalCols || rowspans[colIdx] > 0) {
- if (colIdx >= totalCols) {
- // move down to next row
- colIdx = 0;
- cellIdx = 0;
- rowIdx++;
-
- // decrement all rowspans
- for (j = 0; j < totalCols; j++) {
- if (rowspans[j] > 0) {
- rowspans[j]--;
- }
+ // This method hijacks Ext.view.Table's el scroll method.
+ // This enables us to keep the virtualized scrollbars in sync
+ // with the view. It currently does NOT support animation.
+ elScroll: function(direction, distance, animate) {
+ var me = this,
+ scroller;
+
+ if (direction === "up" || direction === "left") {
+ distance = -distance;
+ }
+
+ if (direction === "down" || direction === "up") {
+ scroller = me.getVerticalScroller();
+
+ //if the grid does not currently need a vertical scroller don't try to update it (EXTJSIV-3891)
+ if (scroller) {
+ scroller.scrollByDeltaY(distance);
+ }
+ } else {
+ scroller = me.getHorizontalScroller();
+
+ //if the grid does not currently need a horizontal scroller don't try to update it (EXTJSIV-3891)
+ if (scroller) {
+ scroller.scrollByDeltaX(distance);
+ }
+ }
+ },
+
+<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> * Requests a recalculation of scrollbars and puts them in if they are needed.
+ */
+ determineScrollbars: function() {
+ // Set a flag so that afterComponentLayout does not recurse back into here.
+ if (this.determineScrollbarsRunning) {
+ return;
+ }
+ this.determineScrollbarsRunning = true;
+ var me = this,
+ view = me.view,
+ box,
+ tableEl,
+ scrollWidth,
+ clientWidth,
+ scrollHeight,
+ clientHeight,
+ verticalScroller = me.verticalScroller,
+ horizontalScroller = me.horizontalScroller,
+ curScrollbars = (verticalScroller && verticalScroller.ownerCt === me ? 1 : 0) |
+ (horizontalScroller && horizontalScroller.ownerCt === me ? 2 : 0),
+ reqScrollbars = 0; // 1 = vertical, 2 = horizontal, 3 = both
+
+ // If we are not collapsed, and the view has been rendered AND filled, then we can determine scrollbars
+ if (!me.collapsed && view && view.viewReady) {
+
+ // Calculate maximum, *scrollbarless* space which the view has available.
+ // It will be the Fit Layout's calculated size, plus the widths of any currently shown scrollbars
+ box = view.el.getSize();
+
+ clientWidth = box.width + ((curScrollbars & 1) ? verticalScroller.width : 0);
+ clientHeight = box.height + ((curScrollbars & 2) ? horizontalScroller.height : 0);
+
+ // Calculate the width of the scrolling block
+ // There will never be a horizontal scrollbar if all columns are flexed.
+
+ scrollWidth = (me.headerCt.query('[flex]').length && !me.headerCt.layout.tooNarrow) ? 0 : me.headerCt.getFullWidth();
+
+ // Calculate the height of the scrolling block
+ if (verticalScroller && verticalScroller.el) {
+ scrollHeight = verticalScroller.getSizeCalculation().height;
+ } else {
+ tableEl = view.el.child('table', true);
+ scrollHeight = tableEl ? tableEl.offsetHeight : 0;
+ }
+
+ // View is too high.
+ // Definitely need a vertical scrollbar
+ if (scrollHeight > clientHeight) {
+ reqScrollbars = 1;
+
+ // But if scrollable block width goes into the zone required by the vertical scrollbar, we'll also need a horizontal
+ if (horizontalScroller && ((clientWidth - scrollWidth) < verticalScroller.width)) {
+ reqScrollbars = 3;
+ }
+ }
+
+ // View height fits. But we stil may need a horizontal scrollbar, and this might necessitate a vertical one.
+ else {
+ // View is too wide.
+ // Definitely need a horizontal scrollbar
+ if (scrollWidth > clientWidth) {
+ reqScrollbars = 2;
+
+ // But if scrollable block height goes into the zone required by the horizontal scrollbar, we'll also need a vertical
+ if (verticalScroller && ((clientHeight - scrollHeight) < horizontalScroller.height)) {
+ reqScrollbars = 3;
}
+ }
+ }
+
+ // If scrollbar requirements have changed, change 'em...
+ if (reqScrollbars !== curScrollbars) {
+
+ // Suspend component layout while we add/remove the docked scrollers
+ me.suspendLayout = true;
+ if (reqScrollbars & 1) {
+ me.showVerticalScroller();
+ } else {
+ me.hideVerticalScroller();
+ }
+ if (reqScrollbars & 2) {
+ me.showHorizontalScroller();
} else {
- colIdx++;
+ me.hideHorizontalScroller();
}
+ me.suspendLayout = false;
+
+ // Lay out the Component.
+ me.doComponentLayout();
+ // Lay out me.items
+ me.getLayout().layout();
}
+ }
+ delete me.determineScrollbarsRunning;
+ },
- // Add the cell info to the list
- cells.push({
- rowIdx: rowIdx,
- cellIdx: cellIdx
- });
+ onViewResize: function() {
+ this.determineScrollbars();
+ },
+
+ afterComponentLayout: function() {
+ this.callParent(arguments);
+ this.determineScrollbars();
+ this.invalidateScroller();
+ },
+
+ onHeaderResize: function() {
+ if (!this.componentLayout.layoutBusy && this.view && this.view.rendered) {
+ this.determineScrollbars();
+ this.invalidateScroller();
+ }
+ },
+
+ afterCollapse: function() {
+ var me = this;
+ if (me.verticalScroller) {
+ me.verticalScroller.saveScrollPos();
+ }
+ if (me.horizontalScroller) {
+ me.horizontalScroller.saveScrollPos();
+ }
+ me.callParent(arguments);
+ },
+
+ afterExpand: function() {
+ var me = this;
+ me.callParent(arguments);
+ if (me.verticalScroller) {
+ me.verticalScroller.restoreScrollPos();
+ }
+ if (me.horizontalScroller) {
+ me.horizontalScroller.restoreScrollPos();
+ }
+ },
+
+<span id='Ext-panel-Table-method-hideHorizontalScroller'> /**
+</span> * Hides the verticalScroller and removes the horizontalScrollerPresentCls.
+ */
+ hideHorizontalScroller: function() {
+ var me = this;
+
+ if (me.horizontalScroller && me.horizontalScroller.ownerCt === me) {
+ me.verticalScroller.setReservedSpace(0);
+ me.removeDocked(me.horizontalScroller, false);
+ me.removeCls(me.horizontalScrollerPresentCls);
+ me.fireEvent('scrollerhide', me.horizontalScroller, 'horizontal');
+ }
- // Increment
- for (j = item.colspan || 1; j; --j) {
- rowspans[colIdx] = item.rowspan || 1;
- ++colIdx;
+ },
+
+<span id='Ext-panel-Table-method-showHorizontalScroller'> /**
+</span> * Shows the horizontalScroller and add the horizontalScrollerPresentCls.
+ */
+ showHorizontalScroller: function() {
+ var me = this;
+
+ if (me.verticalScroller) {
+ me.verticalScroller.setReservedSpace(Ext.getScrollbarSize().height - 1);
+ }
+ if (me.horizontalScroller && me.horizontalScroller.ownerCt !== me) {
+ me.addDocked(me.horizontalScroller);
+ me.addCls(me.horizontalScrollerPresentCls);
+ me.fireEvent('scrollershow', me.horizontalScroller, 'horizontal');
+ }
+ },
+
+<span id='Ext-panel-Table-method-hideVerticalScroller'> /**
+</span> * Hides the verticalScroller and removes the verticalScrollerPresentCls.
+ */
+ hideVerticalScroller: function() {
+ var me = this;
+
+ me.setHeaderReserveOffset(false);
+ if (me.verticalScroller && me.verticalScroller.ownerCt === me) {
+ me.removeDocked(me.verticalScroller, false);
+ me.removeCls(me.verticalScrollerPresentCls);
+ me.fireEvent('scrollerhide', me.verticalScroller, 'vertical');
+ }
+ },
+
+<span id='Ext-panel-Table-method-showVerticalScroller'> /**
+</span> * Shows the verticalScroller and adds the verticalScrollerPresentCls.
+ */
+ showVerticalScroller: function() {
+ var me = this;
+
+ me.setHeaderReserveOffset(true);
+ if (me.verticalScroller && me.verticalScroller.ownerCt !== me) {
+ me.addDocked(me.verticalScroller);
+ me.addCls(me.verticalScrollerPresentCls);
+ me.fireEvent('scrollershow', me.verticalScroller, 'vertical');
+ }
+ },
+
+ setHeaderReserveOffset: function (reserveOffset) {
+ var headerCt = this.headerCt,
+ layout = headerCt.layout;
+
+ // only trigger a layout when reserveOffset is changing
+ if (layout && layout.reserveOffset !== reserveOffset) {
+ layout.reserveOffset = reserveOffset;
+ if (!this.suspendLayout) {
+ headerCt.doLayout();
+ }
+ }
+ },
+
+<span id='Ext-panel-Table-method-invalidateScroller'> /**
+</span> * Invalides scrollers that are present and forces a recalculation. (Not related to showing/hiding the scrollers)
+ */
+ invalidateScroller: function() {
+ var me = this,
+ vScroll = me.verticalScroller,
+ hScroll = me.horizontalScroller;
+
+ if (vScroll) {
+ vScroll.invalidate();
+ }
+ if (hScroll) {
+ hScroll.invalidate();
+ }
+ },
+
+ // refresh the view when a header moves
+ onHeaderMove: function(headerCt, header, fromIdx, toIdx) {
+ this.view.refresh();
+ },
+
+ // Section onHeaderHide is invoked after view.
+ onHeaderHide: function(headerCt, header) {
+ this.invalidateScroller();
+ },
+
+ onHeaderShow: function(headerCt, header) {
+ this.invalidateScroller();
+ },
+
+ getVerticalScroller: function() {
+ return this.getScrollerOwner().down('gridscroller[dock=' + this.verticalScrollDock + ']');
+ },
+
+ getHorizontalScroller: function() {
+ return this.getScrollerOwner().down('gridscroller[dock=bottom]');
+ },
+
+ onMouseWheel: function(e) {
+ var me = this,
+ vertScroller = me.getVerticalScroller(),
+ horizScroller = me.getHorizontalScroller(),
+ scrollDelta = -me.scrollDelta,
+ deltas = e.getWheelDeltas(),
+ deltaX = scrollDelta * deltas.x,
+ deltaY = scrollDelta * deltas.y,
+ vertScrollerEl, horizScrollerEl,
+ vertScrollerElDom, horizScrollerElDom,
+ horizontalCanScrollLeft, horizontalCanScrollRight,
+ verticalCanScrollDown, verticalCanScrollUp;
+
+ // calculate whether or not both scrollbars can scroll right/left and up/down
+ if (horizScroller) {
+ horizScrollerEl = horizScroller.scrollEl;
+ if (horizScrollerEl) {
+ horizScrollerElDom = horizScrollerEl.dom;
+ horizontalCanScrollRight = horizScrollerElDom.scrollLeft !== horizScrollerElDom.scrollWidth - horizScrollerElDom.clientWidth;
+ horizontalCanScrollLeft = horizScrollerElDom.scrollLeft !== 0;
+ }
+ }
+ if (vertScroller) {
+ vertScrollerEl = vertScroller.scrollEl;
+ if (vertScrollerEl) {
+ vertScrollerElDom = vertScrollerEl.dom;
+ verticalCanScrollDown = vertScrollerElDom.scrollTop !== vertScrollerElDom.scrollHeight - vertScrollerElDom.clientHeight;
+ verticalCanScrollUp = vertScrollerElDom.scrollTop !== 0;
}
- ++cellIdx;
}
- return cells;
+ if (horizScroller) {
+ if ((deltaX < 0 && horizontalCanScrollLeft) || (deltaX > 0 && horizontalCanScrollRight)) {
+ e.stopEvent();
+ horizScroller.scrollByDeltaX(deltaX);
+ }
+ }
+ if (vertScroller) {
+ if ((deltaY < 0 && verticalCanScrollUp) || (deltaY > 0 && verticalCanScrollDown)) {
+ e.stopEvent();
+ vertScroller.scrollByDeltaY(deltaY);
+ }
+ }
},
-<span id='Ext-layout-container-Table-method-getTable'> /**
+<span id='Ext-panel-Table-method-onViewReady'> /**
</span> * @private
- * Return the layout's table element, creating it if necessary.
- */
- getTable: function() {
- var table = this.table;
- if (!table) {
- table = this.table = this.getTarget().createChild(
- Ext.apply({
- tag: 'table',
- role: 'presentation',
- cls: this.tableCls,
- cellspacing: 0, //TODO should this be specified or should CSS handle it?
- cn: {tag: 'tbody'}
- }, this.tableAttrs),
- null, true
- );
- }
- return table;
- },
-
-<span id='Ext-layout-container-Table-method-needsDivWrap'> /**
+ * Fires the TablePanel's viewready event when the view declares that its internal DOM is ready
+ */
+ onViewReady: function() {
+ var me = this;
+ me.fireEvent('viewready', me);
+ if (me.deferRowRender) {
+ me.determineScrollbars();
+ me.invalidateScroller();
+ }
+ },
+
+<span id='Ext-panel-Table-method-onViewRefresh'> /**
</span> * @private
- * Opera 10.5 has a bug where if a table cell's child has box-sizing:border-box and padding, it
- * will include that padding in the size of the cell, making it always larger than the
- * shrink-wrapped size of its contents. To get around this we have to wrap the contents in a div
- * and then set that div's width to match the item rendered within it afterLayout. This method
- * determines whether we need the wrapper div; it currently does a straight UA sniff as this bug
- * seems isolated to just Opera 10.5, but feature detection could be added here if needed.
- */
- needsDivWrap: function() {
- return Ext.isOpera10_5;
+ * Determines and invalidates scrollers on view refresh
+ */
+ onViewRefresh: function() {
+ var me = this;
+
+ // Refresh *during* render must be ignored.
+ if (!me.rendering) {
+ this.determineScrollbars();
+ if (this.invalidateScrollerOnRefresh) {
+ this.invalidateScroller();
+ }
+ }
+ },
+
+<span id='Ext-panel-Table-method-setScrollTop'> /**
+</span> * Sets the scrollTop of the TablePanel.
+ * @param {Number} top
+ */
+ setScrollTop: function(top) {
+ var me = this,
+ rootCmp = me.getScrollerOwner(),
+ verticalScroller = me.getVerticalScroller();
+
+ rootCmp.virtualScrollTop = top;
+ if (verticalScroller) {
+ verticalScroller.setScrollTop(top);
+ }
+ },
+
+ getScrollerOwner: function() {
+ var rootCmp = this;
+ if (!this.scrollerOwner) {
+ rootCmp = this.up('[scrollerOwner]');
+ }
+ return rootCmp;
+ },
+
+<span id='Ext-panel-Table-method-scrollByDeltaY'> /**
+</span> * Scrolls the TablePanel by deltaY
+ * @param {Number} deltaY
+ */
+ scrollByDeltaY: function(deltaY) {
+ var verticalScroller = this.getVerticalScroller();
+
+ if (verticalScroller) {
+ verticalScroller.scrollByDeltaY(deltaY);
+ }
+ },
+
+<span id='Ext-panel-Table-method-scrollByDeltaX'> /**
+</span> * Scrolls the TablePanel by deltaX
+ * @param {Number} deltaX
+ */
+ scrollByDeltaX: function(deltaX) {
+ var horizontalScroller = this.getHorizontalScroller();
+
+ if (horizontalScroller) {
+ horizontalScroller.scrollByDeltaX(deltaX);
+ }
+ },
+
+<span id='Ext-panel-Table-method-getLhsMarker'> /**
+</span> * Gets left hand side marker for header resizing.
+ * @private
+ */
+ getLhsMarker: function() {
+ var me = this;
+
+ if (!me.lhsMarker) {
+ me.lhsMarker = Ext.DomHelper.append(me.el, {
+ cls: Ext.baseCSSPrefix + 'grid-resize-marker'
+ }, true);
+ }
+ return me.lhsMarker;
+ },
+
+<span id='Ext-panel-Table-method-getRhsMarker'> /**
+</span> * Gets right hand side marker for header resizing.
+ * @private
+ */
+ getRhsMarker: function() {
+ var me = this;
+
+ if (!me.rhsMarker) {
+ me.rhsMarker = Ext.DomHelper.append(me.el, {
+ cls: Ext.baseCSSPrefix + 'grid-resize-marker'
+ }, true);
+ }
+ return me.rhsMarker;
+ },
+
+<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;
+ },
+
+ onVerticalScroll: function(event, target) {
+ var owner = this.getScrollerOwner(),
+ items = owner.query('tableview'),
+ i = 0,
+ len = items.length;
+
+ for (; i < len; i++) {
+ items[i].el.dom.scrollTop = target.scrollTop;
+ }
+ },
+
+ onHorizontalScroll: function(event, target) {
+ var owner = this.getScrollerOwner(),
+ items = owner.query('tableview'),
+ center = items[1] || items[0];
+
+ center.el.dom.scrollLeft = target.scrollLeft;
+ this.headerCt.el.dom.scrollLeft = target.scrollLeft;
+ },
+
+ // 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(){
+ // may be some duplication here since the horizontal and vertical
+ // scroller may be part of the docked items, but we need to clean
+ // them up in case they aren't visible.
+ Ext.destroy(this.horizontalScroller, this.verticalScroller);
+ this.callParent();
+ },
+
+<span id='Ext-panel-Table-method-reconfigure'> /**
+</span> * Reconfigures the table with a new store/columns. Either the store or the columns can be ommitted if you don't wish
+ * to change them.
+ * @param {Ext.data.Store} store (Optional) The new store.
+ * @param {Object[]} columns (Optional) An array of column configs
+ */
+ reconfigure: function(store, columns) {
+ var me = this,
+ headerCt = me.headerCt;
+
+ if (me.lockable) {
+ me.reconfigureLockable(store, columns);
+ } else {
+ if (columns) {
+ headerCt.suspendLayout = true;
+ headerCt.removeAll();
+ headerCt.add(columns);
+ }
+ if (store) {
+ store = Ext.StoreManager.lookup(store);
+ me.bindStore(store);
+ } else {
+ me.getView().refresh();
+ }
+ if (columns) {
+ headerCt.suspendLayout = false;
+ me.forceComponentLayout();
+ }
+ }
+ me.fireEvent('reconfigure', me);
}
});</pre>
</body>