Upgrade to ExtJS 3.3.1 - Released 11/30/2010
[extjs.git] / src / widgets / layout / TableLayout.js
index 420e4b3..00b88b9 100644 (file)
 /*!
 /*!
- * Ext JS Library 3.1.1
- * Copyright(c) 2006-2010 Ext JS, LLC
- * licensing@extjs.com
- * http://www.extjs.com/license
+ * Ext JS Library 3.3.1
+ * Copyright(c) 2006-2010 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
  */
  */
-/**\r
- * @class Ext.layout.TableLayout\r
- * @extends Ext.layout.ContainerLayout\r
- * <p>This layout allows you to easily render content into an HTML table.  The total number of columns can be\r
- * specified, and rowspan and colspan can be used to create complex layouts within the table.\r
- * This class is intended to be extended or created via the layout:'table' {@link Ext.Container#layout} config,\r
- * and should generally not need to be created directly via the new keyword.</p>\r
- * <p>Note that when creating a layout via config, the layout-specific config properties must be passed in via\r
- * the {@link Ext.Container#layoutConfig} object which will then be applied internally to the layout.  In the\r
- * case of TableLayout, the only valid layout config property is {@link #columns}.  However, the items added to a\r
- * TableLayout can supply the following table-specific config properties:</p>\r
- * <ul>\r
- * <li><b>rowspan</b> Applied to the table cell containing the item.</li>\r
- * <li><b>colspan</b> Applied to the table cell containing the item.</li>\r
- * <li><b>cellId</b> An id applied to the table cell containing the item.</li>\r
- * <li><b>cellCls</b> A CSS class name added to the table cell containing the item.</li>\r
- * </ul>\r
- * <p>The basic concept of building up a TableLayout is conceptually very similar to building up a standard\r
- * HTML table.  You simply add each panel (or "cell") that you want to include along with any span attributes\r
- * specified as the special config properties of rowspan and colspan which work exactly like their HTML counterparts.\r
- * Rather than explicitly creating and nesting rows and columns as you would in HTML, you simply specify the\r
- * total column count in the layoutConfig and start adding panels in their natural order from left to right,\r
- * top to bottom.  The layout will automatically figure out, based on the column count, rowspans and colspans,\r
- * how to position each panel within the table.  Just like with HTML tables, your rowspans and colspans must add\r
- * up correctly in your overall layout or you'll end up with missing and/or extra cells!  Example usage:</p>\r
- * <pre><code>\r
-// This code will generate a layout table that is 3 columns by 2 rows\r
-// with some spanning included.  The basic layout will be:\r
-// +--------+-----------------+\r
-// |   A    |   B             |\r
-// |        |--------+--------|\r
-// |        |   C    |   D    |\r
-// +--------+--------+--------+\r
-var table = new Ext.Panel({\r
-    title: 'Table Layout',\r
-    layout:'table',\r
-    defaults: {\r
-        // applied to each contained panel\r
-        bodyStyle:'padding:20px'\r
-    },\r
-    layoutConfig: {\r
-        // The total column count must be specified here\r
-        columns: 3\r
-    },\r
-    items: [{\r
-        html: '&lt;p&gt;Cell A content&lt;/p&gt;',\r
-        rowspan: 2\r
-    },{\r
-        html: '&lt;p&gt;Cell B content&lt;/p&gt;',\r
-        colspan: 2\r
-    },{\r
-        html: '&lt;p&gt;Cell C content&lt;/p&gt;',\r
-        cellCls: 'highlight'\r
-    },{\r
-        html: '&lt;p&gt;Cell D content&lt;/p&gt;'\r
-    }]\r
-});\r
-</code></pre>\r
- */\r
-Ext.layout.TableLayout = Ext.extend(Ext.layout.ContainerLayout, {\r
-    /**\r
-     * @cfg {Number} columns\r
-     * The total number of columns to create in the table for this layout.  If not specified, all Components added to\r
-     * this layout will be rendered into a single row using one column per Component.\r
-     */\r
-\r
-    // private\r
-    monitorResize:false,\r
-\r
-    type: 'table',\r
-\r
-    targetCls: 'x-table-layout-ct',\r
-\r
-    /**\r
-     * @cfg {Object} tableAttrs\r
-     * <p>An object containing properties which are added to the {@link Ext.DomHelper DomHelper} specification\r
-     * used to create the layout's <tt>&lt;table&gt;</tt> element. Example:</p><pre><code>\r
-{\r
-    xtype: 'panel',\r
-    layout: 'table',\r
-    layoutConfig: {\r
-        tableAttrs: {\r
-            style: {\r
-                width: '100%'\r
-            }\r
-        },\r
-        columns: 3\r
-    }\r
-}</code></pre>\r
-     */\r
-    tableAttrs:null,\r
-\r
-    // private\r
-    setContainer : function(ct){\r
-        Ext.layout.TableLayout.superclass.setContainer.call(this, ct);\r
-\r
-        this.currentRow = 0;\r
-        this.currentColumn = 0;\r
-        this.cells = [];\r
-    },\r
-    \r
-    // private\r
-    onLayout : function(ct, target){\r
-        var cs = ct.items.items, len = cs.length, c, i;\r
-\r
-        if(!this.table){\r
-            target.addClass('x-table-layout-ct');\r
-\r
-            this.table = target.createChild(\r
-                Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true);\r
-        }\r
-        this.renderAll(ct, target);\r
-    },\r
-\r
-    // private\r
-    getRow : function(index){\r
-        var row = this.table.tBodies[0].childNodes[index];\r
-        if(!row){\r
-            row = document.createElement('tr');\r
-            this.table.tBodies[0].appendChild(row);\r
-        }\r
-        return row;\r
-    },\r
-\r
-    // private\r
-    getNextCell : function(c){\r
-        var cell = this.getNextNonSpan(this.currentColumn, this.currentRow);\r
-        var curCol = this.currentColumn = cell[0], curRow = this.currentRow = cell[1];\r
-        for(var rowIndex = curRow; rowIndex < curRow + (c.rowspan || 1); rowIndex++){\r
-            if(!this.cells[rowIndex]){\r
-                this.cells[rowIndex] = [];\r
-            }\r
-            for(var colIndex = curCol; colIndex < curCol + (c.colspan || 1); colIndex++){\r
-                this.cells[rowIndex][colIndex] = true;\r
-            }\r
-        }\r
-        var td = document.createElement('td');\r
-        if(c.cellId){\r
-            td.id = c.cellId;\r
-        }\r
-        var cls = 'x-table-layout-cell';\r
-        if(c.cellCls){\r
-            cls += ' ' + c.cellCls;\r
-        }\r
-        td.className = cls;\r
-        if(c.colspan){\r
-            td.colSpan = c.colspan;\r
-        }\r
-        if(c.rowspan){\r
-            td.rowSpan = c.rowspan;\r
-        }\r
-        this.getRow(curRow).appendChild(td);\r
-        return td;\r
-    },\r
-\r
-    // private\r
-    getNextNonSpan: function(colIndex, rowIndex){\r
-        var cols = this.columns;\r
-        while((cols && colIndex >= cols) || (this.cells[rowIndex] && this.cells[rowIndex][colIndex])) {\r
-            if(cols && colIndex >= cols){\r
-                rowIndex++;\r
-                colIndex = 0;\r
-            }else{\r
-                colIndex++;\r
-            }\r
-        }\r
-        return [colIndex, rowIndex];\r
-    },\r
-\r
-    // private\r
-    renderItem : function(c, position, target){\r
-        // Ensure we have our inner table to get cells to render into.\r
-        if(!this.table){\r
-            this.table = target.createChild(\r
-                Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true);\r
-        }\r
-        if(c && !c.rendered){\r
-            c.render(this.getNextCell(c));\r
-            this.configureItem(c, position);\r
-        }else if(c && !this.isValidParent(c, target)){\r
-            var container = this.getNextCell(c);\r
-            container.insertBefore(c.getPositionEl().dom, null);\r
-            c.container = Ext.get(container);\r
-            this.configureItem(c, position);\r
-        }\r
-    },\r
-\r
-    // private\r
-    isValidParent : function(c, target){\r
-        return c.getPositionEl().up('table', 5).dom.parentNode === (target.dom || target);\r
-    }\r
-\r
-    /**\r
-     * @property activeItem\r
-     * @hide\r
-     */\r
-});\r
-\r
+/**
+ * @class Ext.layout.TableLayout
+ * @extends Ext.layout.ContainerLayout
+ * <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 layout:'table' {@link Ext.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#layoutConfig} object which will then be applied internally to the layout.  In the
+ * case of TableLayout, the only valid layout config property is {@link #columns}.  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>
+ * <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    |
+// +--------+--------+--------+
+var table = new Ext.Panel({
+    title: 'Table Layout',
+    layout:'table',
+    defaults: {
+        // applied to each contained panel
+        bodyStyle:'padding:20px'
+    },
+    layoutConfig: {
+        // The total column count must be specified here
+        columns: 3
+    },
+    items: [{
+        html: '&lt;p&gt;Cell A content&lt;/p&gt;',
+        rowspan: 2
+    },{
+        html: '&lt;p&gt;Cell B content&lt;/p&gt;',
+        colspan: 2
+    },{
+        html: '&lt;p&gt;Cell C content&lt;/p&gt;',
+        cellCls: 'highlight'
+    },{
+        html: '&lt;p&gt;Cell D content&lt;/p&gt;'
+    }]
+});
+</code></pre>
+ */
+Ext.layout.TableLayout = Ext.extend(Ext.layout.ContainerLayout, {
+    /**
+     * @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.
+     */
+
+    // private
+    monitorResize:false,
+
+    type: 'table',
+
+    targetCls: 'x-table-layout-ct',
+
+    /**
+     * @cfg {Object} tableAttrs
+     * <p>An object containing properties which are added to the {@link Ext.DomHelper DomHelper} specification
+     * used to create the layout's <tt>&lt;table&gt;</tt> element. Example:</p><pre><code>
+{
+    xtype: 'panel',
+    layout: 'table',
+    layoutConfig: {
+        tableAttrs: {
+            style: {
+                width: '100%'
+            }
+        },
+        columns: 3
+    }
+}</code></pre>
+     */
+    tableAttrs:null,
+
+    // private
+    setContainer : function(ct){
+        Ext.layout.TableLayout.superclass.setContainer.call(this, ct);
+
+        this.currentRow = 0;
+        this.currentColumn = 0;
+        this.cells = [];
+    },
+    
+    // private
+    onLayout : function(ct, target){
+        var cs = ct.items.items, len = cs.length, c, i;
+
+        if(!this.table){
+            target.addClass('x-table-layout-ct');
+
+            this.table = target.createChild(
+                Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true);
+        }
+        this.renderAll(ct, target);
+    },
+
+    // private
+    getRow : function(index){
+        var row = this.table.tBodies[0].childNodes[index];
+        if(!row){
+            row = document.createElement('tr');
+            this.table.tBodies[0].appendChild(row);
+        }
+        return row;
+    },
+
+    // private
+    getNextCell : function(c){
+        var cell = this.getNextNonSpan(this.currentColumn, this.currentRow);
+        var curCol = this.currentColumn = cell[0], curRow = this.currentRow = cell[1];
+        for(var rowIndex = curRow; rowIndex < curRow + (c.rowspan || 1); rowIndex++){
+            if(!this.cells[rowIndex]){
+                this.cells[rowIndex] = [];
+            }
+            for(var colIndex = curCol; colIndex < curCol + (c.colspan || 1); colIndex++){
+                this.cells[rowIndex][colIndex] = true;
+            }
+        }
+        var td = document.createElement('td');
+        if(c.cellId){
+            td.id = c.cellId;
+        }
+        var cls = 'x-table-layout-cell';
+        if(c.cellCls){
+            cls += ' ' + c.cellCls;
+        }
+        td.className = cls;
+        if(c.colspan){
+            td.colSpan = c.colspan;
+        }
+        if(c.rowspan){
+            td.rowSpan = c.rowspan;
+        }
+        this.getRow(curRow).appendChild(td);
+        return td;
+    },
+
+    // private
+    getNextNonSpan: function(colIndex, rowIndex){
+        var cols = this.columns;
+        while((cols && colIndex >= cols) || (this.cells[rowIndex] && this.cells[rowIndex][colIndex])) {
+            if(cols && colIndex >= cols){
+                rowIndex++;
+                colIndex = 0;
+            }else{
+                colIndex++;
+            }
+        }
+        return [colIndex, rowIndex];
+    },
+
+    // private
+    renderItem : function(c, position, target){
+        // Ensure we have our inner table to get cells to render into.
+        if(!this.table){
+            this.table = target.createChild(
+                Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true);
+        }
+        if(c && !c.rendered){
+            c.render(this.getNextCell(c));
+            this.configureItem(c);
+        }else if(c && !this.isValidParent(c, target)){
+            var container = this.getNextCell(c);
+            container.insertBefore(c.getPositionEl().dom, null);
+            c.container = Ext.get(container);
+            this.configureItem(c);
+        }
+    },
+
+    // private
+    isValidParent : function(c, target){
+        return c.getPositionEl().up('table', 5).dom.parentNode === (target.dom || target);
+    },
+    
+    destroy: function(){
+        delete this.table;
+        Ext.layout.TableLayout.superclass.destroy.call(this);
+    }
+
+    /**
+     * @property activeItem
+     * @hide
+     */
+});
+
 Ext.Container.LAYOUTS['table'] = Ext.layout.TableLayout;
\ No newline at end of file
 Ext.Container.LAYOUTS['table'] = Ext.layout.TableLayout;
\ No newline at end of file