<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-panel-Table'>/**
-</span> * @class Ext.panel.Table
- * @extends Ext.panel.Panel
- * @author Nicolas Ferrero
- * TablePanel is the basis of both TreePanel and GridPanel.
+ <pre class="prettyprint lang-js"><span id='Ext-layout-container-Table'>/**
+</span> * 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 `layout: {type: 'table'}` {@link Ext.container.Container#layout} config, and should generally not
+ * need to be created directly via the new keyword.
*
- * TablePanel aggregates:
+ * 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:
*
- * - a Selection Model
- * - a View
- * - a Store
- * - Scrollers
- * - Ext.grid.header.Container
+ * - **rowspan** Applied to the table cell containing the item.
+ * - **colspan** Applied to the table cell containing the item.
+ * - **cellId** An id applied to the table cell containing the item.
+ * - **cellCls** A CSS class name added to the table cell containing the item.
*
+ * 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:
+ *
+ * @example
+ * 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()
+ * });
*/
-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',
- cls: Ext.baseCSSPrefix + 'grid',
- extraBodyCls: Ext.baseCSSPrefix + 'grid-body',
+ /* End Definitions */
- layout: 'fit',
-<span id='Ext-panel-Table-property-hasView'> /**
-</span> * Boolean to indicate that a view has been injected into the panel.
- * @property hasView
+<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.
*/
- hasView: false,
- // each panel should dictate what viewType and selType to use
- viewType: null,
- selType: 'rowmodel',
+ // private
+ monitorResize:false,
-<span id='Ext-panel-Table-cfg-scrollDelta'> /**
-</span> * @cfg {Number} scrollDelta
- * Number of pixels to scroll when scrolling with mousewheel.
- * Defaults to 40.
- */
- scrollDelta: 40,
+ type: 'table',
-<span id='Ext-panel-Table-cfg-scroll'> /**
-</span> * @cfg {String/Boolean} scroll
- * Valid values are 'both', 'horizontal' or 'vertical'. true implies 'both'. false implies 'none'.
- * Defaults to true.
- */
- scroll: true,
+ // 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-columns'> /**
-</span> * @cfg {Array} 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.
- */
+ clearEl: true, // Base class will not create it if already truthy. Not needed in tables.
-<span id='Ext-panel-Table-cfg-forceFit'> /**
-</span> * @cfg {Boolean} forceFit
- * Specify as <code>true</code> 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..
- */
+ targetCls: Ext.baseCSSPrefix + 'table-layout-ct',
+ tableCls: Ext.baseCSSPrefix + 'table-layout',
+ cellCls: Ext.baseCSSPrefix + 'table-layout-cell',
-<span id='Ext-panel-Table-cfg-hideHeaders'> /**
-</span> * @cfg {Boolean} hideHeaders
- * Specify as <code>true</code> to hide the headers.
+<span id='Ext-layout-container-Table-cfg-tableAttrs'> /**
+</span> * @cfg {Object} tableAttrs
+ * An object containing properties which are added to the {@link Ext.DomHelper DomHelper} specification used to
+ * create the layout's `<table>` element. Example:
+ *
+ * {
+ * xtype: 'panel',
+ * layout: {
+ * type: 'table',
+ * columns: 3,
+ * tableAttrs: {
+ * style: {
+ * width: '100%'
+ * }
+ * }
+ * }
+ * }
*/
+ tableAttrs:null,
-<span id='Ext-panel-Table-cfg-deferRowRender'> /**
-</span> * @cfg {Boolean} deferRowRender <P>Defaults to <code>true</code> to enable deferred row rendering.</p>
- * <p>This allows the GridView 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.</p>
+<span id='Ext-layout-container-Table-cfg-trAttrs'> /**
+</span> * @cfg {Object} trAttrs
+ * An object containing properties which are added to the {@link Ext.DomHelper DomHelper} specification used to
+ * create the layout's <tr> elements.
*/
-<span id='Ext-panel-Table-cfg-sortableColumns'> /**
-</span> * @cfg {Boolean} sortableColumns
- * Defaults to <code>true</code>. Set to <code>false</code> to disable column sorting via clicking the
- * header and via the Sorting menu items.
+<span id='Ext-layout-container-Table-cfg-tdAttrs'> /**
+</span> * @cfg {Object} tdAttrs
+ * An object containing properties which are added to the {@link Ext.DomHelper DomHelper} specification used to
+ * create the layout's <td> elements.
*/
- sortableColumns: true,
-
- 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
- * Defaults to <code>true</code>. Set to <code>false</code> to disable column dragging within this grid.
- */
- enableColumnMove: true,
-
-<span id='Ext-panel-Table-cfg-enableColumnResize'> /**
-</span> * @cfg {Boolean} enableColumnResize
- * Defaults to <code>true</code>. Set to <code>false</code> to disable column resizing within this grid.
- */
- enableColumnResize: true,
-
-<span id='Ext-panel-Table-cfg-enableColumnHide'> /**
-</span> * @cfg {Boolean} enableColumnHide
- * Defaults to <code>true</code>. Set to <code>false</code> 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.store) {
- Ext.Error.raise("You must specify a store 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;
-
- // We cannot buffer this because that will wait for the 30msec from afterLayout (or what
- // ever event triggers it) and we may be in the middle of an animation; that is a bad
- // time to injectView because it causes a layout (by calling add on the container). A
- // throttled func will be called immediately on first call and then block subsequent
- // (rapid fire) calls for 30msec before allowing another call to go through. Similar
- // results, but the action moves from the trailing edge of the interval to the leading
- // edge.
- me.injectView = Ext.Function.createThrottled(me.injectView, 30, me);
-
- if (me.hideHeaders) {
- border = false;
- }
-
- // 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 (Ext.ComponentQuery.query('{locked !== undefined}{processed != true}', me.columns).length) {
- me.self.mixin('lockable', Ext.grid.Lockable);
- me.injectLockable();
- }
- }
-
- me.store = Ext.data.StoreManager.lookup(me.store);
- 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-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);
-
- // 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'
- };
- }
- }
-
- // 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;
- }
-
- if (vertical) {
- me.verticalScroller = Ext.ComponentManager.create(me.initVerticalScroller());
- me.mon(me.verticalScroller, {
- bodyscroll: me.onVerticalScroll,
- scope: me
- });
- }
-
- if (horizontal) {
- me.horizontalScroller = Ext.ComponentManager.create(me.initHorizontalScroller());
- me.mon(me.horizontalScroller, {
- bodyscroll: me.onHorizontalScroll,
- scope: me
- });
- }
-
- me.headerCt.on('columnresize', me.onHeaderResize, me);
- me.relayEvents(me.headerCt, ['columnresize', 'columnmove', 'columnhide', 'columnshow', 'sortchange']);
- me.features = me.features || [];
- 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();
-
- if (view) {
- me.mon(view.store, {
- load: me.onStoreLoad,
- scope: me
- });
- me.mon(view, {
- refresh: me.onViewRefresh,
- scope: me
- });
- this.relayEvents(view, [
-<span id='Ext-panel-Table-event-beforeitemmousedown'> /**
-</span> * @event beforeitemmousedown
- * Fires before the mousedown event on an item is processed. Returns false to cancel the default action.
- * @param {Ext.view.View} this
- * @param {Ext.data.Model} record The record that belongs to the item
- * @param {HTMLElement} item The item's element
- * @param {Number} index The item's index
- * @param {Ext.EventObject} e The raw event object
- */
- 'beforeitemmousedown',
-<span id='Ext-panel-Table-event-beforeitemmouseup'> /**
-</span> * @event beforeitemmouseup
- * Fires before the mouseup event on an item is processed. Returns false to cancel the default action.
- * @param {Ext.view.View} this
- * @param {Ext.data.Model} record The record that belongs to the item
- * @param {HTMLElement} item The item's element
- * @param {Number} index The item's index
- * @param {Ext.EventObject} e The raw event object
- */
- 'beforeitemmouseup',
-<span id='Ext-panel-Table-event-beforeitemmouseenter'> /**
-</span> * @event beforeitemmouseenter
- * Fires before the mouseenter event on an item is processed. Returns false to cancel the default action.
- * @param {Ext.view.View} this
- * @param {Ext.data.Model} record The record that belongs to the item
- * @param {HTMLElement} item The item's element
- * @param {Number} index The item's index
- * @param {Ext.EventObject} e The raw event object
- */
- 'beforeitemmouseenter',
-<span id='Ext-panel-Table-event-beforeitemmouseleave'> /**
-</span> * @event beforeitemmouseleave
- * Fires before the mouseleave event on an item is processed. Returns false to cancel the default action.
- * @param {Ext.view.View} this
- * @param {Ext.data.Model} record The record that belongs to the item
- * @param {HTMLElement} item The item's element
- * @param {Number} index The item's index
- * @param {Ext.EventObject} e The raw event object
- */
- 'beforeitemmouseleave',
-<span id='Ext-panel-Table-event-beforeitemclick'> /**
-</span> * @event beforeitemclick
- * Fires before the click event on an item is processed. Returns false to cancel the default action.
- * @param {Ext.view.View} this
- * @param {Ext.data.Model} record The record that belongs to the item
- * @param {HTMLElement} item The item's element
- * @param {Number} index The item's index
- * @param {Ext.EventObject} e The raw event object
- */
- 'beforeitemclick',
-<span id='Ext-panel-Table-event-beforeitemdblclick'> /**
-</span> * @event beforeitemdblclick
- * Fires before the dblclick event on an item is processed. Returns false to cancel the default action.
- * @param {Ext.view.View} this
- * @param {Ext.data.Model} record The record that belongs to the item
- * @param {HTMLElement} item The item's element
- * @param {Number} index The item's index
- * @param {Ext.EventObject} e The raw event object
- */
- 'beforeitemdblclick',
-<span id='Ext-panel-Table-event-beforeitemcontextmenu'> /**
-</span> * @event beforeitemcontextmenu
- * Fires before the contextmenu event on an item is processed. Returns false to cancel the default action.
- * @param {Ext.view.View} this
- * @param {Ext.data.Model} record The record that belongs to the item
- * @param {HTMLElement} item The item's element
- * @param {Number} index The item's index
- * @param {Ext.EventObject} e The raw event object
- */
- 'beforeitemcontextmenu',
-<span id='Ext-panel-Table-event-itemmousedown'> /**
-</span> * @event itemmousedown
- * Fires when there is a mouse down on an item
- * @param {Ext.view.View} this
- * @param {Ext.data.Model} record The record that belongs to the item
- * @param {HTMLElement} item The item's element
- * @param {Number} index The item's index
- * @param {Ext.EventObject} e The raw event object
- */
- 'itemmousedown',
-<span id='Ext-panel-Table-event-itemmouseup'> /**
-</span> * @event itemmouseup
- * Fires when there is a mouse up on an item
- * @param {Ext.view.View} this
- * @param {Ext.data.Model} record The record that belongs to the item
- * @param {HTMLElement} item The item's element
- * @param {Number} index The item's index
- * @param {Ext.EventObject} e The raw event object
- */
- 'itemmouseup',
-<span id='Ext-panel-Table-event-itemmouseenter'> /**
-</span> * @event itemmouseenter
- * Fires when the mouse enters an item.
- * @param {Ext.view.View} this
- * @param {Ext.data.Model} record The record that belongs to the item
- * @param {HTMLElement} item The item's element
- * @param {Number} index The item's index
- * @param {Ext.EventObject} e The raw event object
- */
- 'itemmouseenter',
-<span id='Ext-panel-Table-event-itemmouseleave'> /**
-</span> * @event itemmouseleave
- * Fires when the mouse leaves an item.
- * @param {Ext.view.View} this
- * @param {Ext.data.Model} record The record that belongs to the item
- * @param {HTMLElement} item The item's element
- * @param {Number} index The item's index
- * @param {Ext.EventObject} e The raw event object
- */
- 'itemmouseleave',
-<span id='Ext-panel-Table-event-itemclick'> /**
-</span> * @event itemclick
- * Fires when an item is clicked.
- * @param {Ext.view.View} this
- * @param {Ext.data.Model} record The record that belongs to the item
- * @param {HTMLElement} item The item's element
- * @param {Number} index The item's index
- * @param {Ext.EventObject} e The raw event object
- */
- 'itemclick',
-<span id='Ext-panel-Table-event-itemdblclick'> /**
-</span> * @event itemdblclick
- * Fires when an item is double clicked.
- * @param {Ext.view.View} this
- * @param {Ext.data.Model} record The record that belongs to the item
- * @param {HTMLElement} item The item's element
- * @param {Number} index The item's index
- * @param {Ext.EventObject} e The raw event object
- */
- 'itemdblclick',
-<span id='Ext-panel-Table-event-itemcontextmenu'> /**
-</span> * @event itemcontextmenu
- * Fires when an item is right clicked.
- * @param {Ext.view.View} this
- * @param {Ext.data.Model} record The record that belongs to the item
- * @param {HTMLElement} item The item's element
- * @param {Number} index The item's index
- * @param {Ext.EventObject} e The raw event object
- */
- 'itemcontextmenu',
-<span id='Ext-panel-Table-event-beforecontainermousedown'> /**
-</span> * @event beforecontainermousedown
- * Fires before the mousedown event on the container is processed. Returns false to cancel the default action.
- * @param {Ext.view.View} this
- * @param {Ext.EventObject} e The raw event object
- */
- 'beforecontainermousedown',
-<span id='Ext-panel-Table-event-beforecontainermouseup'> /**
-</span> * @event beforecontainermouseup
- * Fires before the mouseup event on the container is processed. Returns false to cancel the default action.
- * @param {Ext.view.View} this
- * @param {Ext.EventObject} e The raw event object
- */
- 'beforecontainermouseup',
-<span id='Ext-panel-Table-event-beforecontainermouseover'> /**
-</span> * @event beforecontainermouseover
- * Fires before the mouseover event on the container is processed. Returns false to cancel the default action.
- * @param {Ext.view.View} this
- * @param {Ext.EventObject} e The raw event object
- */
- 'beforecontainermouseover',
-<span id='Ext-panel-Table-event-beforecontainermouseout'> /**
-</span> * @event beforecontainermouseout
- * Fires before the mouseout event on the container is processed. Returns false to cancel the default action.
- * @param {Ext.view.View} this
- * @param {Ext.EventObject} e The raw event object
- */
- 'beforecontainermouseout',
-<span id='Ext-panel-Table-event-beforecontainerclick'> /**
-</span> * @event beforecontainerclick
- * Fires before the click event on the container is processed. Returns false to cancel the default action.
- * @param {Ext.view.View} this
- * @param {Ext.EventObject} e The raw event object
- */
- 'beforecontainerclick',
-<span id='Ext-panel-Table-event-beforecontainerdblclick'> /**
-</span> * @event beforecontainerdblclick
- * Fires before the dblclick event on the container is processed. Returns false to cancel the default action.
- * @param {Ext.view.View} this
- * @param {Ext.EventObject} e The raw event object
- */
- 'beforecontainerdblclick',
-<span id='Ext-panel-Table-event-beforecontainercontextmenu'> /**
-</span> * @event beforecontainercontextmenu
- * Fires before the contextmenu event on the container is processed. Returns false to cancel the default action.
- * @param {Ext.view.View} this
- * @param {Ext.EventObject} e The raw event object
- */
- 'beforecontainercontextmenu',
-<span id='Ext-panel-Table-event-containermouseup'> /**
-</span> * @event containermouseup
- * Fires when there is a mouse up on the container
- * @param {Ext.view.View} this
- * @param {Ext.EventObject} e The raw event object
- */
- 'containermouseup',
-<span id='Ext-panel-Table-event-containermouseover'> /**
-</span> * @event containermouseover
- * Fires when you move the mouse over the container.
- * @param {Ext.view.View} this
- * @param {Ext.EventObject} e The raw event object
- */
- 'containermouseover',
-<span id='Ext-panel-Table-event-containermouseout'> /**
-</span> * @event containermouseout
- * Fires when you move the mouse out of the container.
- * @param {Ext.view.View} this
- * @param {Ext.EventObject} e The raw event object
- */
- 'containermouseout',
-<span id='Ext-panel-Table-event-containerclick'> /**
-</span> * @event containerclick
- * Fires when the container is clicked.
- * @param {Ext.view.View} this
- * @param {Ext.EventObject} e The raw event object
- */
- 'containerclick',
-<span id='Ext-panel-Table-event-containerdblclick'> /**
-</span> * @event containerdblclick
- * Fires when the container is double clicked.
- * @param {Ext.view.View} this
- * @param {Ext.EventObject} e The raw event object
- */
- 'containerdblclick',
-<span id='Ext-panel-Table-event-containercontextmenu'> /**
-</span> * @event containercontextmenu
- * Fires when the container is right clicked.
- * @param {Ext.view.View} this
- * @param {Ext.EventObject} e The raw event object
- */
- 'containercontextmenu',
-
-<span id='Ext-panel-Table-event-selectionchange'> /**
-</span> * @event selectionchange
- * Fires when the selected nodes change. Relayed event from the underlying selection model.
- * @param {Ext.view.View} this
- * @param {Array} selections Array of the selected nodes
- */
- 'selectionchange',
-<span id='Ext-panel-Table-event-beforeselect'> /**
-</span> * @event beforeselect
- * Fires before a selection is made. If any handlers return false, the selection is cancelled.
- * @param {Ext.view.View} this
- * @param {HTMLElement} node The node to be selected
- * @param {Array} selections Array of currently selected nodes
- */
- 'beforeselect'
- ]);
- }
- }
- me.callParent(arguments);
- },
-
- // 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.
+<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.
*/
- initVerticalScroller: function () {
- var me = this,
- ret = me.verticalScroller || {};
-
- Ext.applyIf(ret, {
- xtype: me.verticalScrollerType,
- dock: me.verticalScrollDock,
- store: me.store
- });
-
- return ret;
- },
+ 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;
- getState: function(){
- var state = this.callParent(),
- sorter = this.store.sorters.first(),
- headers = this.headerCt.items.items,
- header,
- len = headers.length,
- i = 0;
+ // Calculate the correct cell structure for the current items
+ cells = this.calculateCells(items);
- state.columns = [];
+ // 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++) {
- header = headers[i];
- state.columns[i] = {
- id: header.headerId
- };
-
- // We only store state which has changed from the initial state.
- // So that current software settings do not override future software settings.
- // Only user-changed state should be saved.
- if (header.hidden !== (header.initialConfig.hidden||header.self.prototype.hidden)) {
- state.columns[i].hidden = header.hidden;
- }
- if (header.sortable !== header.initialConfig.sortable) {
- state.columns[i].sortable = header.sortable;
- }
- if (header.flex) {
- if (header.flex !== header.initialConfig.flex) {
- state.columns[i].flex = header.flex;
- }
- } else {
- if (header.width !== header.initialConfig.width) {
- state.columns[i].width = header.width;
+ 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);
}
}
- }
-
- if (sorter) {
- state.sort = {
- property: sorter.property,
- direction: sorter.direction
- };
- }
- return state;
- },
-
- applyState: function(state) {
- var headers = state.columns,
- length = headers ? headers.length : 0,
- headerCt = this.headerCt,
- items = headerCt.items,
- sorter = state.sort,
- store = this.store,
- i = 0,
- index,
- headerState,
- header;
-
- headerCt.suspendLayout = true;
-
- // Ensure superclass has applied *its* state.
- // AbstractComponent saves dimensions (and anchor/flex) plus collapsed state.
- this.callParent(arguments);
- for (; i < length; ++i) {
- headerState = headers[i];
- header = headerCt.down('gridcolumn[headerId=' + headerState.id + ']');
- index = items.indexOf(header);
- if (i !== index) {
- headerCt.moveHeader(index, i);
+ // 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);
}
- // Only state properties which were saved should be restored.
- // (Only user-changed properties were saved by getState)
- if (Ext.isDefined(headerState.hidden)) {
- header.hidden = headerState.hidden;
+ // Render or move the component into the cell
+ if (!item.rendered) {
+ this.renderItem(item, itemCt, 0);
}
- if (Ext.isDefined(headerState.sortable)) {
- header.sortable = headerState.sortable;
+ else if (!this.isValidParent(item, itemCt, 0)) {
+ this.moveItem(item, itemCt, 0);
}
- if (Ext.isDefined(headerState.flex)) {
- delete header.width;
- header.flex = headerState.flex;
- } else if (Ext.isDefined(headerState.width)) {
- delete header.flex;
- header.minWidth = headerState.width;
- if (header.rendered) {
- header.setWidth(headerState.width);
- } else {
- header.width = headerState.width;
- }
- }
- }
- headerCt.suspendLayout = false;
- // After setting width and flexes while layout is suspended, column Container's Container layout needs running.
- headerCt.doLayout();
-
- 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);
+ // Set the cell properties
+ if (this.tdAttrs) {
+ tdEl.set(this.tdAttrs);
}
- }
- },
-
-<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, {
- deferRowRender: 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
+ tdEl.set({
+ colSpan: item.colspan || 1,
+ rowSpan: item.rowspan || 1,
+ id: item.cellId || '',
+ cls: this.cellCls + ' ' + (item.cellCls || '')
});
- sm.view = me.view;
- me.headerCt.view = me.view;
- me.relayEvents(me.view, ['cellclick', 'celldblclick']);
- }
- return me.view;
- },
-
-<span id='Ext-panel-Table-property-setAutoScroll'> /**
-</span> * @private
- * @override
- * autoScroll is never valid for all classes which extend TablePanel.
- */
- setAutoScroll: Ext.emptyFn,
-
- // 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();
- scroller.scrollByDeltaY(distance);
- } else {
- scroller = me.getHorizontalScroller();
- scroller.scrollByDeltaX(distance);
- }
- },
-
-<span id='Ext-panel-Table-method-injectView'> /**
-</span> * @private
- * Called after this Component has achieved its correct initial size, after all layouts have done their thing.
- * This is so we can add the View only after the initial size is known. This method is throttled 30ms.
- */
- injectView: function() {
- if (!this.hasView && !this.collapsed) {
- var me = this,
- view = me.getView();
-
- me.hasView = true;
- me.add(view);
- function viewReady () {
- // 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
- });
- if (!me.height) {
- me.doComponentLayout();
+ // 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);
}
}
-
- if (view.rendered) {
- viewReady();
- } else {
- view.on({
- afterrender: viewReady,
- single: true
- });
- }
}
- },
- afterExpand: function() {
- // TODO - this is *not* called when part of an accordion!
- this.callParent(arguments);
- if (!this.hasView) {
- this.injectView();
+ // Delete any extra rows
+ rowIdx++;
+ while (tbody.rows[rowIdx]) {
+ tbody.deleteRow(rowIdx);
}
},
-<span id='Ext-panel-Table-method-processEvent'> /**
-</span> * @private
- * Process UI events from the view. Propagate them to whatever internal Components need to process them
- * @param {String} type Event type, eg 'click'
- * @param {TableView} 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 {EventObject} e Original event
- */
- processEvent: function(type, view, cell, recordIndex, cellIndex, e) {
- var me = this,
- header;
+ afterLayout: function() {
+ this.callParent();
- if (cellIndex !== -1) {
- header = me.headerCt.getGridColumns()[cellIndex];
- return header.processEvent.apply(header, arguments);
+ 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());
+ });
}
},
-<span id='Ext-panel-Table-method-determineScrollbars'> /**
-</span> * Request a recalculation of scrollbars and put them in if they are needed.
- */
- determineScrollbars: function() {
- var me = this,
- 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 && me.view && me.view.el && me.view.el.dom.firstChild) {
-
- // 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 = me.layout.getLayoutTargetSize();
- 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 = me.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;
+<span id='Ext-layout-container-Table-method-calculateCells'> /**
+</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 {Object[]} 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;
- // 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;
+ 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]--;
+ }
}
- }
- }
-
- // 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 {
- me.hideHorizontalScroller();
+ colIdx++;
}
- me.suspendLayout = false;
-
- // After docked scrollers are correctly configured, lay out the Component.
- // Set a flag so that afterComponentLayout does not recurse back into here.
- me.changingScrollBars = true;
- me.doComponentLayout(me.getWidth(), me.getHeight(), false, me.ownerCt);
- me.changingScrollBars = false;
}
- }
- },
-
- afterComponentLayout: function() {
- var me = this;
- me.callParent(arguments);
-
- // Insert the View the first time the Panel has a Component layout performed.
- me.injectView();
-
- // Avoid recursion
- if (!me.changingScrollBars) {
- me.determineScrollbars();
- }
- me.invalidateScroller();
- },
-
- onHeaderResize: function() {
- if (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> * Hide the verticalScroller and remove 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');
- }
-
- },
-
-<span id='Ext-panel-Table-method-showHorizontalScroller'> /**
-</span> * Show 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> * Hide the verticalScroller and remove 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> * Show the verticalScroller and add 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;
- 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 / -5,
- deltas = e.getWheelDeltas(),
- deltaX = scrollDelta * deltas.x,
- deltaY = scrollDelta * deltas.y,
- vertScrollerEl, horizScrollerEl,
- vertScrollerElDom, horizScrollerElDom,
- horizontalCanScrollLeft, horizontalCanScrollRight,
- verticalCanScrollDown, verticalCanScrollUp;
+ // Add the cell info to the list
+ cells.push({
+ rowIdx: rowIdx,
+ cellIdx: cellIdx
+ });
- // 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;
+ // Increment
+ for (j = item.colspan || 1; j; --j) {
+ rowspans[colIdx] = item.rowspan || 1;
+ ++colIdx;
}
+ ++cellIdx;
}
- 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);
- }
- }
+ return cells;
},
-<span id='Ext-panel-Table-method-onViewRefresh'> /**
+<span id='Ext-layout-container-Table-method-getTable'> /**
</span> * @private
- * Determine and invalidate scrollers on view refresh
- */
- onViewRefresh: function() {
- this.determineScrollbars();
- if (this.invalidateScrollerOnRefresh) {
- this.invalidateScroller();
- }
- },
-
-<span id='Ext-panel-Table-method-setScrollTop'> /**
-</span> * Sets the scrollTop of the TablePanel.
- * @param {Number} deltaY
- */
- 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} deltaY
- */
- scrollByDeltaX: function(deltaX) {
- var horizontalScroller = this.getVerticalScroller();
-
- if (horizontalScroller) {
- horizontalScroller.scrollByDeltaX(deltaX);
- }
- },
-
-<span id='Ext-panel-Table-method-getLhsMarker'> /**
-</span> * Get left hand side marker for header resizing.
- * @private
- */
- getLhsMarker: function() {
- var me = this;
-
- if (!me.lhsMarker) {
- me.lhsMarker = Ext.core.DomHelper.append(me.el, {
- cls: Ext.baseCSSPrefix + 'grid-resize-marker'
- }, true);
- }
- return me.lhsMarker;
- },
-
-<span id='Ext-panel-Table-method-getRhsMarker'> /**
-</span> * Get right hand side marker for header resizing.
- * @private
- */
- getRhsMarker: function() {
- var me = this;
-
- if (!me.rhsMarker) {
- me.rhsMarker = Ext.core.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);
- },
-
-<span id='Ext-panel-Table-method-reconfigure'> /**
-</span> * Reconfigure the table with a new store/column.
- * Either the store or the column can be ommitted if you don't wish to change them.
- * @param {Ext.data.Store} store The new store.
- * @param {Array} columns An array of column configs
- */
- reconfigure: function(store, columns) {
- var me = this,
- headerCt = me.headerCt;
-
- if (me.lockable) {
- me.reconfigureLockable(store, columns);
- } else {
- headerCt.suspendLayout = true;
- headerCt.removeAll();
- if (columns) {
- headerCt.add(columns);
- } else {
- headerCt.doLayout();
- }
- if (store) {
- store = Ext.StoreManager.lookup(store);
- me.bindStore(store);
- } else {
- me.getView().refresh();
- }
- if (columns) {
- me.forceComponentLayout();
- }
- }
- me.fireEvent('reconfigure', me);
+ * 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'> /**
+</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;
}
});</pre>
</body>