1 <!DOCTYPE html><html><head><title>Sencha Documentation Project</title><link rel="stylesheet" href="../reset.css" type="text/css"><link rel="stylesheet" href="../prettify.css" type="text/css"><link rel="stylesheet" href="../prettify_sa.css" type="text/css"><script type="text/javascript" src="../prettify.js"></script></head><body onload="prettyPrint()"><pre class="prettyprint"><pre><span id='Ext-layout.container.Table'>/**
2 </span> * @class Ext.layout.container.Table
3 * @extends Ext.layout.container.Auto
4 * <p>This layout allows you to easily render content into an HTML table. The total number of columns can be
5 * specified, and rowspan and colspan can be used to create complex layouts within the table.
6 * This class is intended to be extended or created via the <code>layout: {type: 'table'}</code>
7 * {@link Ext.container.Container#layout} config, and should generally not need to be created directly via the new keyword.</p>
8 * <p>Note that when creating a layout via config, the layout-specific config properties must be passed in via
9 * the {@link Ext.container.Container#layout} object which will then be applied internally to the layout. In the
10 * case of TableLayout, the only valid layout config properties are {@link #columns} and {@link #tableAttrs}.
11 * However, the items added to a TableLayout can supply the following table-specific config properties:</p>
13 * <li><b>rowspan</b> Applied to the table cell containing the item.</li>
14 * <li><b>colspan</b> Applied to the table cell containing the item.</li>
15 * <li><b>cellId</b> An id applied to the table cell containing the item.</li>
16 * <li><b>cellCls</b> A CSS class name added to the table cell containing the item.</li>
18 * <p>The basic concept of building up a TableLayout is conceptually very similar to building up a standard
19 * HTML table. You simply add each panel (or "cell") that you want to include along with any span attributes
20 * specified as the special config properties of rowspan and colspan which work exactly like their HTML counterparts.
21 * Rather than explicitly creating and nesting rows and columns as you would in HTML, you simply specify the
22 * total column count in the layoutConfig and start adding panels in their natural order from left to right,
23 * top to bottom. The layout will automatically figure out, based on the column count, rowspans and colspans,
24 * how to position each panel within the table. Just like with HTML tables, your rowspans and colspans must add
25 * up correctly in your overall layout or you'll end up with missing and/or extra cells! Example usage:</p>
26 * {@img Ext.layout.container.Table/Ext.layout.container.Table.png Ext.layout.container.Table container layout}
27 * <pre><code>
28 // This code will generate a layout table that is 3 columns by 2 rows
29 // with some spanning included. The basic layout will be:
30 // +--------+-----------------+
32 // | |--------+--------|
34 // +--------+--------+--------+
35 Ext.create('Ext.panel.Panel', {
36 title: 'Table Layout',
41 // The total column count must be specified here
45 // applied to each contained panel
46 bodyStyle:'padding:20px'
49 html: 'Cell A content',
52 html: 'Cell B content',
55 html: 'Cell C content',
58 html: 'Cell D content'
60 renderTo: Ext.getBody()
62 </code></pre>
65 Ext.define('Ext.layout.container.Table', {
67 /* Begin Definitions */
69 alias: ['layout.table'],
70 extend: 'Ext.layout.container.Auto',
71 alternateClassName: 'Ext.layout.TableLayout',
75 <span id='Ext-layout.container.Table-cfg-columns'> /**
76 </span> * @cfg {Number} columns
77 * The total number of columns to create in the table for this layout. If not specified, all Components added to
78 * this layout will be rendered into a single row using one column per Component.
86 // Table layout is a self-sizing layout. When an item of for example, a dock layout, the Panel must expand to accommodate
87 // a table layout. See in particular AbstractDock::onLayout for use of this flag.
90 clearEl: true, // Base class will not create it if already truthy. Not needed in tables.
92 targetCls: Ext.baseCSSPrefix + 'table-layout-ct',
93 tableCls: Ext.baseCSSPrefix + 'table-layout',
94 cellCls: Ext.baseCSSPrefix + 'table-layout-cell',
96 <span id='Ext-layout.container.Table-cfg-tableAttrs'> /**
97 </span> * @cfg {Object} tableAttrs
98 * <p>An object containing properties which are added to the {@link Ext.core.DomHelper DomHelper} specification
99 * used to create the layout's <tt>&lt;table&gt;</tt> element. Example:</p><pre><code>
111 }</code></pre>
115 <span id='Ext-layout.container.Table-method-renderItems'> /**
117 * Iterates over all passed items, ensuring they are rendered in a cell in the proper
118 * location in the table structure.
120 renderItems: function(items) {
121 var tbody = this.getTable().tBodies[0],
125 cells, curCell, rowIdx, cellIdx, item, trEl, tdEl, itemCt;
127 // Calculate the correct cell structure for the current items
128 cells = this.calculateCells(items);
130 // Loop over each cell and compare to the current cells in the table, inserting/
131 // removing/moving cells as needed, and making sure each item is rendered into
133 for (; i < len; i++) {
135 rowIdx = curCell.rowIdx;
136 cellIdx = curCell.cellIdx;
139 // If no row present, create and insert one
142 trEl = tbody.insertRow(rowIdx);
145 // If no cell present, create and insert one
146 itemCt = tdEl = Ext.get(trEl.cells[cellIdx] || trEl.insertCell(cellIdx));
147 if (this.needsDivWrap()) { //create wrapper div if needed - see docs below
148 itemCt = tdEl.first() || tdEl.createChild({tag: 'div'});
149 itemCt.setWidth(null);
152 // Render or move the component into the cell
153 if (!item.rendered) {
154 this.renderItem(item, itemCt, 0);
156 else if (!this.isValidParent(item, itemCt, 0)) {
157 this.moveItem(item, itemCt, 0);
160 // Set the cell properties
162 colSpan: item.colspan || 1,
163 rowSpan: item.rowspan || 1,
164 id: item.cellId || '',
165 cls: this.cellCls + ' ' + (item.cellCls || '')
168 // If at the end of a row, remove any extra cells
169 if (!cells[i + 1] || cells[i + 1].rowIdx !== rowIdx) {
171 while (trEl.cells[cellIdx]) {
172 trEl.deleteCell(cellIdx);
177 // Delete any extra rows
179 while (tbody.rows[rowIdx]) {
180 tbody.deleteRow(rowIdx);
184 afterLayout: function() {
187 if (this.needsDivWrap()) {
188 // set wrapper div width to match layed out item - see docs below
189 Ext.Array.forEach(this.getLayoutItems(), function(item) {
190 Ext.fly(item.el.dom.parentNode).setWidth(item.getWidth());
195 <span id='Ext-layout.container.Table-method-calculateCells'> /**
197 * Determine the row and cell indexes for each component, taking into consideration
198 * the number of columns and each item's configured colspan/rowspan values.
199 * @param {Array} items The layout components
200 * @return {Array} List of row and cell indexes for each of the components
202 calculateCells: function(items) {
207 totalCols = this.columns || Infinity,
208 rowspans = [], //rolling list of active rowspans for each column
213 for (; i < len; i++) {
216 // Find the first available row/col slot not taken up by a spanning cell
217 while (colIdx >= totalCols || rowspans[colIdx] > 0) {
218 if (colIdx >= totalCols) {
219 // move down to next row
224 // decrement all rowspans
225 for (j = 0; j < totalCols; j++) {
226 if (rowspans[j] > 0) {
235 // Add the cell info to the list
242 rowspans[colIdx] = item.rowspan || 1;
243 colIdx += item.colspan || 1;
250 <span id='Ext-layout.container.Table-method-getTable'> /**
252 * Return the layout's table element, creating it if necessary.
254 getTable: function() {
255 var table = this.table;
257 table = this.table = this.getTarget().createChild(
260 role: 'presentation',
262 cellspacing: 0, //TODO should this be specified or should CSS handle it?
271 <span id='Ext-layout.container.Table-method-needsDivWrap'> /**
273 * Opera 10.5 has a bug where if a table cell's child has box-sizing:border-box and padding, it
274 * will include that padding in the size of the cell, making it always larger than the
275 * shrink-wrapped size of its contents. To get around this we have to wrap the contents in a div
276 * and then set that div's width to match the item rendered within it afterLayout. This method
277 * determines whether we need the wrapper div; it currently does a straight UA sniff as this bug
278 * seems isolated to just Opera 10.5, but feature detection could be added here if needed.
280 needsDivWrap: function() {
281 return Ext.isOpera10_5;
283 });</pre></pre></body></html>