/javascripts/lib/src/widgets/layout/TableLayout.js
JavaScript | 205 lines | 89 code | 16 blank | 100 comment | 22 complexity | cd46f2d3d8143555f95e2eefc641ec7e MD5 | raw file
Possible License(s): GPL-3.0
1/*! 2 * Ext JS Library 3.2.1 3 * Copyright(c) 2006-2010 Ext JS, Inc. 4 * licensing@extjs.com 5 * http://www.extjs.com/license 6 */ 7/** 8 * @class Ext.layout.TableLayout 9 * @extends Ext.layout.ContainerLayout 10 * <p>This layout allows you to easily render content into an HTML table. The total number of columns can be 11 * specified, and rowspan and colspan can be used to create complex layouts within the table. 12 * This class is intended to be extended or created via the layout:'table' {@link Ext.Container#layout} config, 13 * and should generally not need to be created directly via the new keyword.</p> 14 * <p>Note that when creating a layout via config, the layout-specific config properties must be passed in via 15 * the {@link Ext.Container#layoutConfig} object which will then be applied internally to the layout. In the 16 * case of TableLayout, the only valid layout config property is {@link #columns}. However, the items added to a 17 * TableLayout can supply the following table-specific config properties:</p> 18 * <ul> 19 * <li><b>rowspan</b> Applied to the table cell containing the item.</li> 20 * <li><b>colspan</b> Applied to the table cell containing the item.</li> 21 * <li><b>cellId</b> An id applied to the table cell containing the item.</li> 22 * <li><b>cellCls</b> A CSS class name added to the table cell containing the item.</li> 23 * </ul> 24 * <p>The basic concept of building up a TableLayout is conceptually very similar to building up a standard 25 * HTML table. You simply add each panel (or "cell") that you want to include along with any span attributes 26 * specified as the special config properties of rowspan and colspan which work exactly like their HTML counterparts. 27 * Rather than explicitly creating and nesting rows and columns as you would in HTML, you simply specify the 28 * total column count in the layoutConfig and start adding panels in their natural order from left to right, 29 * top to bottom. The layout will automatically figure out, based on the column count, rowspans and colspans, 30 * how to position each panel within the table. Just like with HTML tables, your rowspans and colspans must add 31 * up correctly in your overall layout or you'll end up with missing and/or extra cells! Example usage:</p> 32 * <pre><code> 33// This code will generate a layout table that is 3 columns by 2 rows 34// with some spanning included. The basic layout will be: 35// +--------+-----------------+ 36// | A | B | 37// | |--------+--------| 38// | | C | D | 39// +--------+--------+--------+ 40var table = new Ext.Panel({ 41 title: 'Table Layout', 42 layout:'table', 43 defaults: { 44 // applied to each contained panel 45 bodyStyle:'padding:20px' 46 }, 47 layoutConfig: { 48 // The total column count must be specified here 49 columns: 3 50 }, 51 items: [{ 52 html: '<p>Cell A content</p>', 53 rowspan: 2 54 },{ 55 html: '<p>Cell B content</p>', 56 colspan: 2 57 },{ 58 html: '<p>Cell C content</p>', 59 cellCls: 'highlight' 60 },{ 61 html: '<p>Cell D content</p>' 62 }] 63}); 64</code></pre> 65 */ 66Ext.layout.TableLayout = Ext.extend(Ext.layout.ContainerLayout, { 67 /** 68 * @cfg {Number} columns 69 * The total number of columns to create in the table for this layout. If not specified, all Components added to 70 * this layout will be rendered into a single row using one column per Component. 71 */ 72 73 // private 74 monitorResize:false, 75 76 type: 'table', 77 78 targetCls: 'x-table-layout-ct', 79 80 /** 81 * @cfg {Object} tableAttrs 82 * <p>An object containing properties which are added to the {@link Ext.DomHelper DomHelper} specification 83 * used to create the layout's <tt><table></tt> element. Example:</p><pre><code> 84{ 85 xtype: 'panel', 86 layout: 'table', 87 layoutConfig: { 88 tableAttrs: { 89 style: { 90 width: '100%' 91 } 92 }, 93 columns: 3 94 } 95}</code></pre> 96 */ 97 tableAttrs:null, 98 99 // private 100 setContainer : function(ct){ 101 Ext.layout.TableLayout.superclass.setContainer.call(this, ct); 102 103 this.currentRow = 0; 104 this.currentColumn = 0; 105 this.cells = []; 106 }, 107 108 // private 109 onLayout : function(ct, target){ 110 var cs = ct.items.items, len = cs.length, c, i; 111 112 if(!this.table){ 113 target.addClass('x-table-layout-ct'); 114 115 this.table = target.createChild( 116 Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true); 117 } 118 this.renderAll(ct, target); 119 }, 120 121 // private 122 getRow : function(index){ 123 var row = this.table.tBodies[0].childNodes[index]; 124 if(!row){ 125 row = document.createElement('tr'); 126 this.table.tBodies[0].appendChild(row); 127 } 128 return row; 129 }, 130 131 // private 132 getNextCell : function(c){ 133 var cell = this.getNextNonSpan(this.currentColumn, this.currentRow); 134 var curCol = this.currentColumn = cell[0], curRow = this.currentRow = cell[1]; 135 for(var rowIndex = curRow; rowIndex < curRow + (c.rowspan || 1); rowIndex++){ 136 if(!this.cells[rowIndex]){ 137 this.cells[rowIndex] = []; 138 } 139 for(var colIndex = curCol; colIndex < curCol + (c.colspan || 1); colIndex++){ 140 this.cells[rowIndex][colIndex] = true; 141 } 142 } 143 var td = document.createElement('td'); 144 if(c.cellId){ 145 td.id = c.cellId; 146 } 147 var cls = 'x-table-layout-cell'; 148 if(c.cellCls){ 149 cls += ' ' + c.cellCls; 150 } 151 td.className = cls; 152 if(c.colspan){ 153 td.colSpan = c.colspan; 154 } 155 if(c.rowspan){ 156 td.rowSpan = c.rowspan; 157 } 158 this.getRow(curRow).appendChild(td); 159 return td; 160 }, 161 162 // private 163 getNextNonSpan: function(colIndex, rowIndex){ 164 var cols = this.columns; 165 while((cols && colIndex >= cols) || (this.cells[rowIndex] && this.cells[rowIndex][colIndex])) { 166 if(cols && colIndex >= cols){ 167 rowIndex++; 168 colIndex = 0; 169 }else{ 170 colIndex++; 171 } 172 } 173 return [colIndex, rowIndex]; 174 }, 175 176 // private 177 renderItem : function(c, position, target){ 178 // Ensure we have our inner table to get cells to render into. 179 if(!this.table){ 180 this.table = target.createChild( 181 Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true); 182 } 183 if(c && !c.rendered){ 184 c.render(this.getNextCell(c)); 185 this.configureItem(c, position); 186 }else if(c && !this.isValidParent(c, target)){ 187 var container = this.getNextCell(c); 188 container.insertBefore(c.getPositionEl().dom, null); 189 c.container = Ext.get(container); 190 this.configureItem(c, position); 191 } 192 }, 193 194 // private 195 isValidParent : function(c, target){ 196 return c.getPositionEl().up('table', 5).dom.parentNode === (target.dom || target); 197 } 198 199 /** 200 * @property activeItem 201 * @hide 202 */ 203}); 204 205Ext.Container.LAYOUTS['table'] = Ext.layout.TableLayout;