Upgrade to ExtJS 4.0.2 - Released 06/09/2011
[extjs.git] / docs / source / AbstractPanel.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="../prettify/prettify.css" type="text/css" rel="stylesheet" />
7   <script type="text/javascript" src="../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-panel-AbstractPanel'>/**
19 </span> * @class Ext.panel.AbstractPanel
20  * @extends Ext.container.Container
21  * &lt;p&gt;A base class which provides methods common to Panel classes across the Sencha product range.&lt;/p&gt;
22  * &lt;p&gt;Please refer to sub class's documentation&lt;/p&gt;
23  */
24 Ext.define('Ext.panel.AbstractPanel', {
25
26     /* Begin Definitions */
27
28     extend: 'Ext.container.Container',
29
30     requires: ['Ext.util.MixedCollection', 'Ext.core.Element', 'Ext.toolbar.Toolbar'],
31
32     /* End Definitions */
33
34 <span id='Ext-panel-AbstractPanel-cfg-baseCls'>    /**
35 </span>     * @cfg {String} baseCls
36      * The base CSS class to apply to this panel's element (defaults to &lt;code&gt;'x-panel'&lt;/code&gt;).
37      */
38     baseCls : Ext.baseCSSPrefix + 'panel',
39
40 <span id='Ext-panel-AbstractPanel-cfg-bodyPadding'>    /**
41 </span>     * @cfg {Number/String} bodyPadding
42      * A shortcut for setting a padding style on the body element. The value can either be
43      * a number to be applied to all sides, or a normal css string describing padding.
44      * Defaults to &lt;code&gt;undefined&lt;/code&gt;.
45      */
46
47 <span id='Ext-panel-AbstractPanel-cfg-bodyBorder'>    /**
48 </span>     * @cfg {Boolean} bodyBorder
49      * A shortcut to add or remove the border on the body of a panel. This only applies to a panel which has the {@link #frame} configuration set to `true`.
50      * Defaults to &lt;code&gt;undefined&lt;/code&gt;.
51      */
52
53 <span id='Ext-panel-AbstractPanel-cfg-bodyStyle'>    /**
54 </span>     * @cfg {String/Object/Function} bodyStyle
55      * Custom CSS styles to be applied to the panel's body element, which can be supplied as a valid CSS style string,
56      * an object containing style property name/value pairs or a function that returns such a string or object.
57      * For example, these two formats are interpreted to be equivalent:&lt;pre&gt;&lt;code&gt;
58 bodyStyle: 'background:#ffc; padding:10px;'
59
60 bodyStyle: {
61     background: '#ffc',
62     padding: '10px'
63 }
64      * &lt;/code&gt;&lt;/pre&gt;
65      */
66
67 <span id='Ext-panel-AbstractPanel-cfg-bodyCls'>    /**
68 </span>     * @cfg {String/Array} bodyCls
69      * A CSS class, space-delimited string of classes, or array of classes to be applied to the panel's body element.
70      * The following examples are all valid:&lt;pre&gt;&lt;code&gt;
71 bodyCls: 'foo'
72 bodyCls: 'foo bar'
73 bodyCls: ['foo', 'bar']
74      * &lt;/code&gt;&lt;/pre&gt;
75      */
76
77     isPanel: true,
78
79     componentLayout: 'dock',
80
81 <span id='Ext-panel-AbstractPanel-cfg-defaultDockWeights'>    /**
82 </span>     * @cfg {Object} defaultDockWeights
83      * This object holds the default weights applied to dockedItems that have no weight. These start with a
84      * weight of 1, to allow negative weights to insert before top items and are odd numbers
85      * so that even weights can be used to get between different dock orders.
86      * 
87      * To make default docking order match border layout, do this:
88      * &lt;pre&gt;&lt;code&gt;
89 Ext.panel.AbstractPanel.prototype.defaultDockWeights = { top: 1, bottom: 3, left: 5, right: 7 };&lt;/code&gt;&lt;/pre&gt;
90      * Changing these defaults as above or individually on this object will effect all Panels.
91      * To change the defaults on a single panel, you should replace the entire object:
92      * &lt;pre&gt;&lt;code&gt;
93 initComponent: function () {
94     // NOTE: Don't change members of defaultDockWeights since the object is shared.
95     this.defaultDockWeights = { top: 1, bottom: 3, left: 5, right: 7 };
96
97     this.callParent();
98 }&lt;/code&gt;&lt;/pre&gt;
99      *
100      * To change only one of the default values, you do this:
101      * &lt;pre&gt;&lt;code&gt;
102 initComponent: function () {
103     // NOTE: Don't change members of defaultDockWeights since the object is shared.
104     this.defaultDockWeights = Ext.applyIf({ top: 10 }, this.defaultDockWeights);
105
106     this.callParent();
107 }&lt;/code&gt;&lt;/pre&gt;
108      */
109     defaultDockWeights: { top: 1, left: 3, right: 5, bottom: 7 },
110
111     renderTpl: ['&lt;div class=&quot;{baseCls}-body&lt;tpl if=&quot;bodyCls&quot;&gt; {bodyCls}&lt;/tpl&gt; {baseCls}-body-{ui}&lt;tpl if=&quot;uiCls&quot;&gt;&lt;tpl for=&quot;uiCls&quot;&gt; {parent.baseCls}-body-{parent.ui}-{.}&lt;/tpl&gt;&lt;/tpl&gt;&quot;&lt;tpl if=&quot;bodyStyle&quot;&gt; style=&quot;{bodyStyle}&quot;&lt;/tpl&gt;&gt;&lt;/div&gt;'],
112
113     // TODO: Move code examples into product-specific files. The code snippet below is Touch only.
114 <span id='Ext-panel-AbstractPanel-cfg-dockedItems'>    /**
115 </span>     * @cfg {Object/Array} dockedItems
116      * A component or series of components to be added as docked items to this panel.
117      * The docked items can be docked to either the top, right, left or bottom of a panel.
118      * This is typically used for things like toolbars or tab bars:
119      * &lt;pre&gt;&lt;code&gt;
120 var panel = new Ext.panel.Panel({
121     fullscreen: true,
122     dockedItems: [{
123         xtype: 'toolbar',
124         dock: 'top',
125         items: [{
126             text: 'Docked to the top'
127         }]
128     }]
129 });&lt;/code&gt;&lt;/pre&gt;
130      */
131
132     border: true,
133
134     initComponent : function() {
135         var me = this;
136
137         me.addEvents(
138 <span id='Ext-panel-AbstractPanel-event-bodyresize'>            /**
139 </span>             * @event bodyresize
140              * Fires after the Panel has been resized.
141              * @param {Ext.panel.Panel} p the Panel which has been resized.
142              * @param {Number} width The Panel body's new width.
143              * @param {Number} height The Panel body's new height.
144              */
145             'bodyresize'
146             // // inherited
147             // 'activate',
148             // // inherited
149             // 'deactivate'
150         );
151
152         Ext.applyIf(me.renderSelectors, {
153             body: '.' + me.baseCls + '-body'
154         });
155
156         //!frame
157         //!border
158
159         if (me.frame &amp;&amp; me.border &amp;&amp; me.bodyBorder === undefined) {
160             me.bodyBorder = false;
161         }
162         if (me.frame &amp;&amp; me.border &amp;&amp; (me.bodyBorder === false || me.bodyBorder === 0)) {
163             me.manageBodyBorders = true;
164         }
165
166         me.callParent();
167     },
168
169     // @private
170     initItems : function() {
171         var me = this,
172             items = me.dockedItems;
173
174         me.callParent();
175         me.dockedItems = Ext.create('Ext.util.MixedCollection', false, me.getComponentId);
176         if (items) {
177             me.addDocked(items);
178         }
179     },
180
181 <span id='Ext-panel-AbstractPanel-method-getDockedComponent'>    /**
182 </span>     * Finds a docked component by id, itemId or position. Also see {@link #getDockedItems}
183      * @param {String/Number} comp The id, itemId or position of the docked component (see {@link #getComponent} for details)
184      * @return {Ext.Component} The docked component (if found)
185      */
186     getDockedComponent: function(comp) {
187         if (Ext.isObject(comp)) {
188             comp = comp.getItemId();
189         }
190         return this.dockedItems.get(comp);
191     },
192
193 <span id='Ext-panel-AbstractPanel-method-getComponent'>    /**
194 </span>     * Attempts a default component lookup (see {@link Ext.container.Container#getComponent}). If the component is not found in the normal
195      * items, the dockedItems are searched and the matched component (if any) returned (see {@loink #getDockedComponent}). Note that docked
196      * items will only be matched by component id or itemId -- if you pass a numeric index only non-docked child components will be searched.
197      * @param {String/Number} comp The component id, itemId or position to find
198      * @return {Ext.Component} The component (if found)
199      */
200     getComponent: function(comp) {
201         var component = this.callParent(arguments);
202         if (component === undefined &amp;&amp; !Ext.isNumber(comp)) {
203             // If the arg is a numeric index skip docked items
204             component = this.getDockedComponent(comp);
205         }
206         return component;
207     },
208
209 <span id='Ext-panel-AbstractPanel-method-initBodyStyles'>    /**
210 </span>     * Parses the {@link bodyStyle} config if available to create a style string that will be applied to the body element.
211      * This also includes {@link bodyPadding} and {@link bodyBorder} if available.
212      * @return {String} A CSS style string with body styles, padding and border.
213      * @private
214      */
215     initBodyStyles: function() {
216         var me = this,
217             bodyStyle = me.bodyStyle,
218             styles = [],
219             Element = Ext.core.Element,
220             prop;
221
222         if (Ext.isFunction(bodyStyle)) {
223             bodyStyle = bodyStyle();
224         }
225         if (Ext.isString(bodyStyle)) {
226             styles = bodyStyle.split(';');
227         } else {
228             for (prop in bodyStyle) {
229                 if (bodyStyle.hasOwnProperty(prop)) {
230                     styles.push(prop + ':' + bodyStyle[prop]);
231                 }
232             }
233         }
234
235         if (me.bodyPadding !== undefined) {
236             styles.push('padding: ' + Element.unitizeBox((me.bodyPadding === true) ? 5 : me.bodyPadding));
237         }
238         if (me.frame &amp;&amp; me.bodyBorder) {
239             if (!Ext.isNumber(me.bodyBorder)) {
240                 me.bodyBorder = 1;
241             }
242             styles.push('border-width: ' + Element.unitizeBox(me.bodyBorder));
243         }
244         delete me.bodyStyle;
245         return styles.length ? styles.join(';') : undefined;
246     },
247
248 <span id='Ext-panel-AbstractPanel-method-initBodyCls'>    /**
249 </span>     * Parse the {@link bodyCls} config if available to create a comma-delimited string of
250      * CSS classes to be applied to the body element.
251      * @return {String} The CSS class(es)
252      * @private
253      */
254     initBodyCls: function() {
255         var me = this,
256             cls = '',
257             bodyCls = me.bodyCls;
258
259         if (bodyCls) {
260             Ext.each(bodyCls, function(v) {
261                 cls += &quot; &quot; + v;
262             });
263             delete me.bodyCls;
264         }
265         return cls.length &gt; 0 ? cls : undefined;
266     },
267
268 <span id='Ext-panel-AbstractPanel-method-initRenderData'>    /**
269 </span>     * Initialized the renderData to be used when rendering the renderTpl.
270      * @return {Object} Object with keys and values that are going to be applied to the renderTpl
271      * @private
272      */
273     initRenderData: function() {
274         return Ext.applyIf(this.callParent(), {
275             bodyStyle: this.initBodyStyles(),
276             bodyCls: this.initBodyCls()
277         });
278     },
279
280 <span id='Ext-panel-AbstractPanel-method-addDocked'>    /**
281 </span>     * Adds docked item(s) to the panel.
282      * @param {Object/Array} component The Component or array of components to add. The components
283      * must include a 'dock' parameter on each component to indicate where it should be docked ('top', 'right',
284      * 'bottom', 'left').
285      * @param {Number} pos (optional) The index at which the Component will be added
286      */
287     addDocked : function(items, pos) {
288         var me = this,
289             i = 0,
290             item, length;
291
292         items = me.prepareItems(items);
293         length = items.length;
294
295         for (; i &lt; length; i++) {
296             item = items[i];
297             item.dock = item.dock || 'top';
298
299             // Allow older browsers to target docked items to style without borders
300             if (me.border === false) {
301                 // item.cls = item.cls || '' + ' ' + me.baseCls + '-noborder-docked-' + item.dock;
302             }
303
304             if (pos !== undefined) {
305                 me.dockedItems.insert(pos + i, item);
306             }
307             else {
308                 me.dockedItems.add(item);
309             }
310             item.onAdded(me, i);
311             me.onDockedAdd(item);
312         }
313
314         // Set flag which means that beforeLayout will not veto the layout due to the size not changing
315         me.componentLayout.childrenChanged = true;
316         if (me.rendered &amp;&amp; !me.suspendLayout) {
317             me.doComponentLayout();
318         }
319         return items;
320     },
321
322     // Placeholder empty functions
323     onDockedAdd : Ext.emptyFn,
324     onDockedRemove : Ext.emptyFn,
325
326 <span id='Ext-panel-AbstractPanel-method-insertDocked'>    /**
327 </span>     * Inserts docked item(s) to the panel at the indicated position.
328      * @param {Number} pos The index at which the Component will be inserted
329      * @param {Object/Array} component. The Component or array of components to add. The components
330      * must include a 'dock' paramater on each component to indicate where it should be docked ('top', 'right',
331      * 'bottom', 'left').
332      */
333     insertDocked : function(pos, items) {
334         this.addDocked(items, pos);
335     },
336
337 <span id='Ext-panel-AbstractPanel-method-removeDocked'>    /**
338 </span>     * Removes the docked item from the panel.
339      * @param {Ext.Component} item. The Component to remove.
340      * @param {Boolean} autoDestroy (optional) Destroy the component after removal.
341      */
342     removeDocked : function(item, autoDestroy) {
343         var me = this,
344             layout,
345             hasLayout;
346
347         if (!me.dockedItems.contains(item)) {
348             return item;
349         }
350
351         layout = me.componentLayout;
352         hasLayout = layout &amp;&amp; me.rendered;
353
354         if (hasLayout) {
355             layout.onRemove(item);
356         }
357
358         me.dockedItems.remove(item);
359         item.onRemoved();
360         me.onDockedRemove(item);
361
362         if (autoDestroy === true || (autoDestroy !== false &amp;&amp; me.autoDestroy)) {
363             item.destroy();
364         }
365
366         if (hasLayout &amp;&amp; !autoDestroy) {
367             layout.afterRemove(item);
368         }
369
370
371         // Set flag which means that beforeLayout will not veto the layout due to the size not changing
372         me.componentLayout.childrenChanged = true;
373         if (!me.destroying &amp;&amp; !me.suspendLayout) {
374             me.doComponentLayout();
375         }
376
377         return item;
378     },
379
380 <span id='Ext-panel-AbstractPanel-method-getDockedItems'>    /**
381 </span>     * Retrieve an array of all currently docked Components.
382      * @param {String} cqSelector A {@link Ext.ComponentQuery ComponentQuery} selector string to filter the returned items.
383      * @return {Array} An array of components.
384      */
385     getDockedItems : function(cqSelector) {
386         var me = this,
387             defaultWeight = me.defaultDockWeights,
388             dockedItems;
389
390         if (me.dockedItems &amp;&amp; me.dockedItems.items.length) {
391             // Allow filtering of returned docked items by CQ selector.
392             if (cqSelector) {
393                 dockedItems = Ext.ComponentQuery.query(cqSelector, me.dockedItems.items);
394             } else {
395                 dockedItems = me.dockedItems.items.slice();
396             }
397
398             Ext.Array.sort(dockedItems, function(a, b) {
399                 // Docked items are ordered by their visual representation by default (t,l,r,b)
400                 var aw = a.weight || defaultWeight[a.dock],
401                     bw = b.weight || defaultWeight[b.dock];
402                 if (Ext.isNumber(aw) &amp;&amp; Ext.isNumber(bw)) {
403                     return aw - bw;
404                 }
405                 return 0;
406             });
407
408             return dockedItems;
409         }
410         return [];
411     },
412
413     // inherit docs
414     addUIClsToElement: function(cls, force) {
415         var me = this,
416             result = me.callParent(arguments),
417             classes = [Ext.baseCSSPrefix + cls, me.baseCls + '-body-' + cls, me.baseCls + '-body-' + me.ui + '-' + cls],
418             array, i;
419
420         if (!force &amp;&amp; me.rendered) {
421             if (me.bodyCls) {
422                 me.body.addCls(me.bodyCls);
423             } else {
424                 me.body.addCls(classes);
425             }
426         } else {
427             if (me.bodyCls) {
428                 array = me.bodyCls.split(' ');
429
430                 for (i = 0; i &lt; classes.length; i++) {
431                     if (!Ext.Array.contains(array, classes[i])) {
432                         array.push(classes[i]);
433                     }
434                 }
435
436                 me.bodyCls = array.join(' ');
437             } else {
438                 me.bodyCls = classes.join(' ');
439             }
440         }
441
442         return result;
443     },
444
445     // inherit docs
446     removeUIClsFromElement: function(cls, force) {
447         var me = this,
448             result = me.callParent(arguments),
449             classes = [Ext.baseCSSPrefix + cls, me.baseCls + '-body-' + cls, me.baseCls + '-body-' + me.ui + '-' + cls],
450             array, i;
451
452         if (!force &amp;&amp; me.rendered) {
453             if (me.bodyCls) {
454                 me.body.removeCls(me.bodyCls);
455             } else {
456                 me.body.removeCls(classes);
457             }
458         } else {
459             if (me.bodyCls) {
460                 array = me.bodyCls.split(' ');
461
462                 for (i = 0; i &lt; classes.length; i++) {
463                     Ext.Array.remove(array, classes[i]);
464                 }
465
466                 me.bodyCls = array.join(' ');
467             }
468         }
469
470         return result;
471     },
472
473     // inherit docs
474     addUIToElement: function(force) {
475         var me = this,
476             cls = me.baseCls + '-body-' + me.ui,
477             array;
478
479         me.callParent(arguments);
480
481         if (!force &amp;&amp; me.rendered) {
482             if (me.bodyCls) {
483                 me.body.addCls(me.bodyCls);
484             } else {
485                 me.body.addCls(cls);
486             }
487         } else {
488             if (me.bodyCls) {
489                 array = me.bodyCls.split(' ');
490
491                 if (!Ext.Array.contains(array, cls)) {
492                     array.push(cls);
493                 }
494
495                 me.bodyCls = array.join(' ');
496             } else {
497                 me.bodyCls = cls;
498             }
499         }
500     },
501
502     // inherit docs
503     removeUIFromElement: function() {
504         var me = this,
505             cls = me.baseCls + '-body-' + me.ui,
506             array;
507
508         me.callParent(arguments);
509
510         if (me.rendered) {
511             if (me.bodyCls) {
512                 me.body.removeCls(me.bodyCls);
513             } else {
514                 me.body.removeCls(cls);
515             }
516         } else {
517             if (me.bodyCls) {
518                 array = me.bodyCls.split(' ');
519                 Ext.Array.remove(array, cls);
520                 me.bodyCls = array.join(' ');
521             } else {
522                 me.bodyCls = cls;
523             }
524         }
525     },
526
527     // @private
528     getTargetEl : function() {
529         return this.body;
530     },
531
532     getRefItems: function(deep) {
533         var items = this.callParent(arguments),
534             // deep fetches all docked items, and their descendants using '*' selector and then '* *'
535             dockedItems = this.getDockedItems(deep ? '*,* *' : undefined),
536             ln = dockedItems.length,
537             i = 0,
538             item;
539
540         // Find the index where we go from top/left docked items to right/bottom docked items
541         for (; i &lt; ln; i++) {
542             item = dockedItems[i];
543             if (item.dock === 'right' || item.dock === 'bottom') {
544                 break;
545             }
546         }
547
548         // Return docked items in the top/left position before our container items, and
549         // return right/bottom positioned items after our container items.
550         // See AbstractDock.renderItems() for more information.
551         return Ext.Array.splice(dockedItems, 0, i).concat(items).concat(dockedItems);
552     },
553
554     beforeDestroy: function(){
555         var docked = this.dockedItems,
556             c;
557
558         if (docked) {
559             while ((c = docked.first())) {
560                 this.removeDocked(c, true);
561             }
562         }
563         this.callParent();
564     },
565
566     setBorder: function(border) {
567         var me = this;
568         me.border = (border !== undefined) ? border : true;
569         if (me.rendered) {
570             me.doComponentLayout();
571         }
572     }
573 });</pre>
574 </body>
575 </html>