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