Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / docs / source / Column2.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5   <title>The source code</title>
6   <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
7   <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
8   <style type="text/css">
9     .highlight { display: block; background-color: #ddd; }
10   </style>
11   <script type="text/javascript">
12     function highlight() {
13       document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
14     }
15   </script>
16 </head>
17 <body onload="prettyPrint(); highlight();">
18   <pre class="prettyprint lang-js"><span id='Ext-layout-container-Column'>/**
19 </span> * This is the layout style of choice for creating structural layouts in a multi-column format where the width of each
20  * column can be specified as a percentage or fixed width, but the height is allowed to vary based on the content. This
21  * class is intended to be extended or created via the layout:'column' {@link Ext.container.Container#layout} config,
22  * and should generally not need to be created directly via the new keyword.
23  *
24  * ColumnLayout does not have any direct config options (other than inherited ones), but it does support a specific
25  * config property of `columnWidth` that can be included in the config of any panel added to it. The layout will use
26  * the columnWidth (if present) or width of each panel during layout to determine how to size each panel. If width or
27  * columnWidth is not specified for a given panel, its width will default to the panel's width (or auto).
28  *
29  * The width property is always evaluated as pixels, and must be a number greater than or equal to 1. The columnWidth
30  * property is always evaluated as a percentage, and must be a decimal value greater than 0 and less than 1 (e.g., .25).
31  *
32  * The basic rules for specifying column widths are pretty simple. The logic makes two passes through the set of
33  * contained panels. During the first layout pass, all panels that either have a fixed width or none specified (auto)
34  * are skipped, but their widths are subtracted from the overall container width.
35  *
36  * During the second pass, all panels with columnWidths are assigned pixel widths in proportion to their percentages
37  * based on the total **remaining** container width. In other words, percentage width panels are designed to fill
38  * the space left over by all the fixed-width and/or auto-width panels. Because of this, while you can specify any
39  * number of columns with different percentages, the columnWidths must always add up to 1 (or 100%) when added
40  * together, otherwise your layout may not render as expected.
41  *
42  *     @example
43  *     // All columns are percentages -- they must add up to 1
44  *     Ext.create('Ext.panel.Panel', {
45  *         title: 'Column Layout - Percentage Only',
46  *         width: 350,
47  *         height: 250,
48  *         layout:'column',
49  *         items: [{
50  *             title: 'Column 1',
51  *             columnWidth: .25
52  *         },{
53  *             title: 'Column 2',
54  *             columnWidth: .55
55  *         },{
56  *             title: 'Column 3',
57  *             columnWidth: .20
58  *         }],
59  *         renderTo: Ext.getBody()
60  *     });
61  *
62  *     // Mix of width and columnWidth -- all columnWidth values must add up
63  *     // to 1. The first column will take up exactly 120px, and the last two
64  *     // columns will fill the remaining container width.
65  *
66  *     Ext.create('Ext.Panel', {
67  *         title: 'Column Layout - Mixed',
68  *         width: 350,
69  *         height: 250,
70  *         layout:'column',
71  *         items: [{
72  *             title: 'Column 1',
73  *             width: 120
74  *         },{
75  *             title: 'Column 2',
76  *             columnWidth: .7
77  *         },{
78  *             title: 'Column 3',
79  *             columnWidth: .3
80  *         }],
81  *         renderTo: Ext.getBody()
82  *     });
83  */
84 Ext.define('Ext.layout.container.Column', {
85
86     extend: 'Ext.layout.container.Auto',
87     alias: ['layout.column'],
88     alternateClassName: 'Ext.layout.ColumnLayout',
89
90     type: 'column',
91
92     itemCls: Ext.baseCSSPrefix + 'column',
93
94     targetCls: Ext.baseCSSPrefix + 'column-layout-ct',
95
96     scrollOffset: 0,
97
98     bindToOwnerCtComponent: false,
99
100     getRenderTarget : function() {
101         if (!this.innerCt) {
102
103             // the innerCt prevents wrapping and shuffling while
104             // the container is resizing
105             this.innerCt = this.getTarget().createChild({
106                 cls: Ext.baseCSSPrefix + 'column-inner'
107             });
108
109             // Column layout uses natural HTML flow to arrange the child items.
110             // To ensure that all browsers (I'm looking at you IE!) add the bottom margin of the last child to the
111             // containing element height, we create a zero-sized element with style clear:both to force a &quot;new line&quot;
112             this.clearEl = this.innerCt.createChild({
113                 cls: Ext.baseCSSPrefix + 'clear',
114                 role: 'presentation'
115             });
116         }
117         return this.innerCt;
118     },
119
120     // private
121     onLayout : function() {
122         var me = this,
123             target = me.getTarget(),
124             items = me.getLayoutItems(),
125             len = items.length,
126             item,
127             i,
128             parallelMargins = [],
129             itemParallelMargins,
130             size,
131             availableWidth,
132             columnWidth;
133
134         size = me.getLayoutTargetSize();
135         if (size.width &lt; len * 10) { // Don't lay out in impossibly small target (probably display:none, or initial, unsized Container)
136             return;
137         }
138
139         // On the first pass, for all except IE6-7, we lay out the items with no scrollbars visible using style overflow: hidden.
140         // If, after the layout, it is detected that there is vertical overflow,
141         // we will recurse back through here. Do not adjust overflow style at that time.
142         if (me.adjustmentPass) {
143             if (Ext.isIE6 || Ext.isIE7 || Ext.isIEQuirks) {
144                 size.width = me.adjustedWidth;
145             }
146         } else {
147             i = target.getStyle('overflow');
148             if (i &amp;&amp; i != 'hidden') {
149                 me.autoScroll = true;
150                 if (!(Ext.isIE6 || Ext.isIE7 || Ext.isIEQuirks)) {
151                     target.setStyle('overflow', 'hidden');
152                     size = me.getLayoutTargetSize();
153                 }
154             }
155         }
156
157         availableWidth = size.width - me.scrollOffset;
158         me.innerCt.setWidth(availableWidth);
159
160         // some columns can be percentages while others are fixed
161         // so we need to make 2 passes
162         for (i = 0; i &lt; len; i++) {
163             item = items[i];
164             itemParallelMargins = parallelMargins[i] = item.getEl().getMargin('lr');
165             if (!item.columnWidth) {
166                 availableWidth -= (item.getWidth() + itemParallelMargins);
167             }
168         }
169
170         availableWidth = availableWidth &lt; 0 ? 0 : availableWidth;
171         for (i = 0; i &lt; len; i++) {
172             item = items[i];
173             if (item.columnWidth) {
174                 columnWidth = Math.floor(item.columnWidth * availableWidth) - parallelMargins[i];
175                 me.setItemSize(item, columnWidth, item.height);
176             } else {
177                 me.layoutItem(item);
178             }
179         }
180
181         // After the first pass on an autoScroll layout, restore the overflow settings if it had been changed (only changed for non-IE6)
182         if (!me.adjustmentPass &amp;&amp; me.autoScroll) {
183
184             // If there's a vertical overflow, relay with scrollbars
185             target.setStyle('overflow', 'auto');
186             me.adjustmentPass = (target.dom.scrollHeight &gt; size.height);
187             if (Ext.isIE6 || Ext.isIE7 || Ext.isIEQuirks) {
188                 me.adjustedWidth = size.width - Ext.getScrollBarWidth();
189             } else {
190                 target.setStyle('overflow', 'auto');
191             }
192
193             // If the layout caused height overflow, recurse back and recalculate (with overflow setting restored on non-IE6)
194             if (me.adjustmentPass) {
195                 me.onLayout();
196             }
197         }
198         delete me.adjustmentPass;
199     },
200
201     configureItem: function(item) {
202         this.callParent(arguments);
203
204         if (item.columnWidth) {
205             item.layoutManagedWidth = 1;
206         }
207     }
208 });</pre>
209 </body>
210 </html>