Upgrade to ExtJS 3.1.1 - Released 02/08/2010
[extjs.git] / docs / source / ContainerLayout.html
1 <html>\r
2 <head>\r
3   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    \r
4   <title>The source code</title>\r
5     <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />\r
6     <script type="text/javascript" src="../resources/prettify/prettify.js"></script>\r
7 </head>\r
8 <body  onload="prettyPrint();">\r
9     <pre class="prettyprint lang-js"><div id="cls-Ext.layout.ContainerLayout"></div>/**
10  * @class Ext.layout.ContainerLayout
11  * <p>This class is intended to be extended or created via the <tt><b>{@link Ext.Container#layout layout}</b></tt>
12  * configuration property.  See <tt><b>{@link Ext.Container#layout}</b></tt> for additional details.</p>
13  */
14 Ext.layout.ContainerLayout = Ext.extend(Object, {
15     <div id="cfg-Ext.layout.ContainerLayout-extraCls"></div>/**
16      * @cfg {String} extraCls
17      * <p>An optional extra CSS class that will be added to the container. This can be useful for adding
18      * customized styles to the container or any of its children using standard CSS rules. See
19      * {@link Ext.Component}.{@link Ext.Component#ctCls ctCls} also.</p>
20      * <p><b>Note</b>: <tt>extraCls</tt> defaults to <tt>''</tt> except for the following classes
21      * which assign a value by default:
22      * <div class="mdetail-params"><ul>
23      * <li>{@link Ext.layout.AbsoluteLayout Absolute Layout} : <tt>'x-abs-layout-item'</tt></li>
24      * <li>{@link Ext.layout.Box Box Layout} : <tt>'x-box-item'</tt></li>
25      * <li>{@link Ext.layout.ColumnLayout Column Layout} : <tt>'x-column'</tt></li>
26      * </ul></div>
27      * To configure the above Classes with an extra CSS class append to the default.  For example,
28      * for ColumnLayout:<pre><code>
29      * extraCls: 'x-column custom-class'
30      * </code></pre>
31      * </p>
32      */
33     <div id="cfg-Ext.layout.ContainerLayout-renderHidden"></div>/**
34      * @cfg {Boolean} renderHidden
35      * True to hide each contained item on render (defaults to false).
36      */
37
38     <div id="prop-Ext.layout.ContainerLayout-activeItem"></div>/**
39      * A reference to the {@link Ext.Component} that is active.  For example, <pre><code>
40      * if(myPanel.layout.activeItem.id == 'item-1') { ... }
41      * </code></pre>
42      * <tt>activeItem</tt> only applies to layout styles that can display items one at a time
43      * (like {@link Ext.layout.AccordionLayout}, {@link Ext.layout.CardLayout}
44      * and {@link Ext.layout.FitLayout}).  Read-only.  Related to {@link Ext.Container#activeItem}.
45      * @type {Ext.Component}
46      * @property activeItem
47      */
48
49     // private
50     monitorResize:false,
51     // private
52     activeItem : null,
53
54     constructor : function(config){
55         this.id = Ext.id(null, 'ext-layout-');
56         Ext.apply(this, config);
57     },
58
59     type: 'container',
60
61     /* Workaround for how IE measures autoWidth elements.  It prefers bottom-up measurements
62       whereas other browser prefer top-down.  We will hide all target child elements before we measure and
63       put them back to get an accurate measurement.
64     */
65     IEMeasureHack : function(target, viewFlag) {
66         var tChildren = target.dom.childNodes, tLen = tChildren.length, c, d = [], e, i, ret;
67         for (i = 0 ; i < tLen ; i++) {
68             c = tChildren[i];
69             e = Ext.get(c);
70             if (e) {
71                 d[i] = e.getStyle('display');
72                 e.setStyle({display: 'none'});
73             }
74         }
75         ret = target ? target.getViewSize(viewFlag) : {};
76         for (i = 0 ; i < tLen ; i++) {
77             c = tChildren[i];
78             e = Ext.get(c);
79             if (e) {
80                 e.setStyle({display: d[i]});
81             }
82         }
83         return ret;
84     },
85
86     // Placeholder for the derived layouts
87     getLayoutTargetSize : Ext.EmptyFn,
88
89     // private
90     layout : function(){
91         var ct = this.container, target = ct.getLayoutTarget();
92         if(!(this.hasLayout || Ext.isEmpty(this.targetCls))){
93             target.addClass(this.targetCls);
94         }
95         this.onLayout(ct, target);
96         ct.fireEvent('afterlayout', ct, this);
97     },
98
99     // private
100     onLayout : function(ct, target){
101         this.renderAll(ct, target);
102     },
103
104     // private
105     isValidParent : function(c, target){
106         return target && c.getPositionEl().dom.parentNode == (target.dom || target);
107     },
108
109     // private
110     renderAll : function(ct, target){
111         var items = ct.items.items, i, c, len = items.length;
112         for(i = 0; i < len; i++) {
113             c = items[i];
114             if(c && (!c.rendered || !this.isValidParent(c, target))){
115                 this.renderItem(c, i, target);
116             }
117         }
118     },
119
120     // private
121     renderItem : function(c, position, target){
122         if(c){
123             if(!c.rendered){
124                 c.render(target, position);
125                 this.configureItem(c, position);
126             }else if(!this.isValidParent(c, target)){
127                 if(Ext.isNumber(position)){
128                     position = target.dom.childNodes[position];
129                 }
130                 target.dom.insertBefore(c.getPositionEl().dom, position || null);
131                 c.container = target;
132                 this.configureItem(c, position);
133             }
134         }
135     },
136
137     // private.
138     // Get all rendered items to lay out.
139     getRenderedItems: function(ct){
140         var t = ct.getLayoutTarget(), cti = ct.items.items, len = cti.length, i, c, items = [];
141         for (i = 0; i < len; i++) {
142             if((c = cti[i]).rendered && this.isValidParent(c, t)){
143                 items.push(c);
144             }
145         };
146         return items;
147     },
148
149     // private
150     configureItem: function(c, position){
151         if(this.extraCls){
152             var t = c.getPositionEl ? c.getPositionEl() : c;
153             t.addClass(this.extraCls);
154         }
155         // If we are forcing a layout, do so *before* we hide so elements have height/width
156         if(c.doLayout && this.forceLayout){
157             c.doLayout();
158         }
159         if (this.renderHidden && c != this.activeItem) {
160             c.hide();
161         }
162     },
163
164     onRemove: function(c){
165          if(this.activeItem == c){
166             delete this.activeItem;
167          }
168          if(c.rendered && this.extraCls){
169             var t = c.getPositionEl ? c.getPositionEl() : c;
170             t.removeClass(this.extraCls);
171         }
172     },
173
174     afterRemove: function(c){
175         if(c.removeRestore){
176             c.removeMode = 'container';
177             delete c.removeRestore;
178         }
179     },
180
181     // private
182     onResize: function(){
183         var ct = this.container,
184             b;
185         if(ct.collapsed){
186             return;
187         }
188         if(b = ct.bufferResize){
189             // Only allow if we should buffer the layout
190             if(ct.shouldBufferLayout()){
191                 if(!this.resizeTask){
192                     this.resizeTask = new Ext.util.DelayedTask(this.runLayout, this);
193                     this.resizeBuffer = Ext.isNumber(b) ? b : 50;
194                 }
195                 ct.layoutPending = true;
196                 this.resizeTask.delay(this.resizeBuffer);
197             }
198         }else{
199             this.runLayout();
200         }
201     },
202
203     runLayout: function(){
204         var ct = this.container;
205         // AutoLayout is known to require the recursive doLayout call, others need this currently (BorderLayout for example)
206         // but shouldn't.  A more extensive review will take place for 3.2 which requires a ContainerMgr with hierarchy lookups.
207         //this.layout();
208         //ct.onLayout();
209         ct.doLayout();
210         delete ct.layoutPending;
211     },
212
213     // private
214     setContainer : function(ct){
215         if (!Ext.LayoutManager) {
216             Ext.LayoutManager = {};
217         }
218
219         /* This monitorResize flag will be renamed soon as to avoid confusion
220         * with the Container version which hooks onWindowResize to doLayout
221         *
222         * monitorResize flag in this context attaches the resize event between
223         * a container and it's layout
224         */
225
226         if(this.monitorResize && ct != this.container){
227             var old = this.container;
228             if(old){
229                 old.un(old.resizeEvent, this.onResize, this);
230             }
231             if(ct){
232                 ct.on(ct.resizeEvent, this.onResize, this);
233             }
234         }
235         this.container = ct;
236     },
237
238     // private
239     parseMargins : function(v){
240         if(Ext.isNumber(v)){
241             v = v.toString();
242         }
243         var ms = v.split(' ');
244         var len = ms.length;
245         if(len == 1){
246             ms[1] = ms[2] = ms[3] = ms[0];
247         } else if(len == 2){
248             ms[2] = ms[0];
249             ms[3] = ms[1];
250         } else if(len == 3){
251             ms[3] = ms[1];
252         }
253         return {
254             top:parseInt(ms[0], 10) || 0,
255             right:parseInt(ms[1], 10) || 0,
256             bottom:parseInt(ms[2], 10) || 0,
257             left:parseInt(ms[3], 10) || 0
258         };
259     },
260
261     <div id="prop-Ext.layout.ContainerLayout-fieldTpl"></div>/**
262      * The {@link Ext.Template Ext.Template} used by Field rendering layout classes (such as
263      * {@link Ext.layout.FormLayout}) to create the DOM structure of a fully wrapped,
264      * labeled and styled form Field. A default Template is supplied, but this may be
265      * overriden to create custom field structures. The template processes values returned from
266      * {@link Ext.layout.FormLayout#getTemplateArgs}.
267      * @property fieldTpl
268      * @type Ext.Template
269      */
270     fieldTpl: (function() {
271         var t = new Ext.Template(
272             '<div class="x-form-item {itemCls}" tabIndex="-1">',
273                 '<label for="{id}" style="{labelStyle}" class="x-form-item-label">{label}{labelSeparator}</label>',
274                 '<div class="x-form-element" id="x-form-el-{id}" style="{elementStyle}">',
275                 '</div><div class="{clearCls}"></div>',
276             '</div>'
277         );
278         t.disableFormats = true;
279         return t.compile();
280     })(),
281
282     /*
283      * Destroys this layout. This is a template method that is empty by default, but should be implemented
284      * by subclasses that require explicit destruction to purge event handlers or remove DOM nodes.
285      * @protected
286      */
287     destroy : function(){
288         if(!Ext.isEmpty(this.targetCls)){
289             var target = this.container.getLayoutTarget();
290             if(target){
291                 target.removeClass(this.targetCls);
292             }
293         }
294     }
295 });</pre>    \r
296 </body>\r
297 </html>