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