Upgrade to ExtJS 4.0.1 - Released 05/18/2011
[extjs.git] / docs / source / Panel3.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-Panel-method-constructor'><span id='Ext-panel-Panel'>/**
19 </span></span> * @class Ext.panel.Panel
20  * @extends Ext.panel.AbstractPanel
21  * &lt;p&gt;Panel is a container that has specific functionality and structural components that make
22  * it the perfect building block for application-oriented user interfaces.&lt;/p&gt;
23  * &lt;p&gt;Panels are, by virtue of their inheritance from {@link Ext.container.Container}, capable
24  * of being configured with a {@link Ext.container.Container#layout layout}, and containing child Components.&lt;/p&gt;
25  * &lt;p&gt;When either specifying child {@link Ext.Component#items items} of a Panel, or dynamically {@link Ext.container.Container#add adding} Components
26  * to a Panel, remember to consider how you wish the Panel to arrange those child elements, and whether
27  * those child elements need to be sized using one of Ext&amp;#39;s built-in &lt;code&gt;&lt;b&gt;{@link Ext.container.Container#layout layout}&lt;/b&gt;&lt;/code&gt; schemes. By
28  * default, Panels use the {@link Ext.layout.container.Auto Auto} scheme. This simply renders
29  * child components, appending them one after the other inside the Container, and &lt;b&gt;does not apply any sizing&lt;/b&gt;
30  * at all.&lt;/p&gt;
31  * {@img Ext.panel.Panel/panel.png Panel components}
32  * &lt;p&gt;A Panel may also contain {@link #bbar bottom} and {@link #tbar top} toolbars, along with separate
33  * {@link #header}, {@link #footer} and {@link #body} sections (see {@link #frame} for additional
34  * information).&lt;/p&gt;
35  * &lt;p&gt;Panel also provides built-in {@link #collapsible collapsible, expandable} and {@link #closable} behavior.
36  * Panels can be easily dropped into any {@link Ext.container.Container Container} or layout, and the
37  * layout and rendering pipeline is {@link Ext.container.Container#add completely managed by the framework}.&lt;/p&gt;
38  * &lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; By default, the &lt;code&gt;{@link #closable close}&lt;/code&gt; header tool &lt;i&gt;destroys&lt;/i&gt; the Panel resulting in removal of the Panel
39  * and the destruction of any descendant Components. This makes the Panel object, and all its descendants &lt;b&gt;unusable&lt;/b&gt;. To enable the close
40  * tool to simply &lt;i&gt;hide&lt;/i&gt; a Panel for later re-use, configure the Panel with &lt;b&gt;&lt;code&gt;{@link #closeAction closeAction: 'hide'}&lt;/code&gt;&lt;/b&gt;.&lt;/p&gt;
41  * &lt;p&gt;Usually, Panels are used as constituents within an application, in which case, they would be used as child items of Containers,
42  * and would themselves use Ext.Components as child {@link #items}. However to illustrate simply rendering a Panel into the document,
43  * here&amp;#39;s how to do it:&lt;pre&gt;&lt;code&gt;
44 Ext.create('Ext.panel.Panel', {
45     title: 'Hello',
46     width: 200,
47     html: '&amp;lt;p&amp;gt;World!&amp;lt;/p&amp;gt;',
48     renderTo: document.body
49 });
50 &lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
51  * &lt;p&gt;A more realistic scenario is a Panel created to house input fields which will not be rendered, but used as a constituent part of a Container:&lt;pre&gt;&lt;code&gt;
52 var filterPanel = Ext.create('Ext.panel.Panel', {
53     bodyPadding: 5,  // Don&amp;#39;t want content to crunch against the borders
54     title: 'Filters',
55     items: [{
56         xtype: 'datefield',
57         fieldLabel: 'Start date'
58     }, {
59         xtype: 'datefield',
60         fieldLabel: 'End date'
61     }]
62 });
63 &lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
64  * &lt;p&gt;Note that the Panel above is not configured to render into the document, nor is it configured with a size or position. In a real world scenario,
65  * the Container into which the Panel is added will use a {@link #layout} to render, size and position its child Components.&lt;/p&gt;
66  * &lt;p&gt;Panels will often use specific {@link #layout}s to provide an application with shape and structure by containing and arranging child
67  * Components: &lt;pre&gt;&lt;code&gt;
68 var resultsPanel = Ext.create('Ext.panel.Panel', {
69     title: 'Results',
70     width: 600,
71     height: 400,
72     renderTo: document.body,
73     layout: {
74         type: 'vbox',       // Arrange child items vertically
75         align: 'stretch',    // Each takes up full width
76         padding: 5
77     },
78     items: [{               // Results grid specified as a config object with an xtype of 'grid'
79         xtype: 'grid',
80         columns: [{header: 'Column One'}],            // One header just for show. There&amp;#39;s no data,
81         store: Ext.create('Ext.data.ArrayStore', {}), // A dummy empty data store
82         flex: 1                                       // Use 1/3 of Container&amp;#39;s height (hint to Box layout)
83     }, {
84         xtype: 'splitter'   // A splitter between the two child items
85     }, {                    // Details Panel specified as a config object (no xtype defaults to 'panel').
86         title: 'Details',
87         bodyPadding: 5,
88         items: [{
89             fieldLabel: 'Data item',
90             xtype: 'textfield'
91         }], // An array of form fields
92         flex: 2             // Use 2/3 of Container&amp;#39;s height (hint to Box layout)
93     }]
94 });
95 &lt;/code&gt;&lt;/pre&gt;
96  * The example illustrates one possible method of displaying search results. The Panel contains a grid with the resulting data arranged
97  * in rows. Each selected row may be displayed in detail in the Panel below. The {@link Ext.layout.container.VBox vbox} layout is used
98  * to arrange the two vertically. It is configured to stretch child items horizontally to full width. Child items may either be configured
99  * with a numeric height, or with a &lt;code&gt;flex&lt;/code&gt; value to distribute available space proportionately.&lt;/p&gt;
100  * &lt;p&gt;This Panel itself may be a child item of, for exaple, a {@link Ext.tab.Panel} which will size its child items to fit within its
101  * content area.&lt;/p&gt;
102  * &lt;p&gt;Using these techniques, as long as the &lt;b&gt;layout&lt;/b&gt; is chosen and configured correctly, an application may have any level of
103  * nested containment, all dynamically sized according to configuration, the user&amp;#39;s preference and available browser size.&lt;/p&gt;
104  * @constructor
105  * @param {Object} config The config object
106  * @xtype panel
107  */
108 Ext.define('Ext.panel.Panel', {
109     extend: 'Ext.panel.AbstractPanel',
110     requires: [
111         'Ext.panel.Header',
112         'Ext.fx.Anim',
113         'Ext.util.KeyMap',
114         'Ext.panel.DD',
115         'Ext.XTemplate',
116         'Ext.layout.component.Dock'
117     ],
118     alias: 'widget.panel',
119     alternateClassName: 'Ext.Panel',
120
121 <span id='Ext-panel-Panel-cfg-collapsedCls'>    /**
122 </span>     * @cfg {String} collapsedCls
123      * A CSS class to add to the panel&amp;#39;s element after it has been collapsed (defaults to
124      * &lt;code&gt;'collapsed'&lt;/code&gt;).
125      */
126     collapsedCls: 'collapsed',
127
128 <span id='Ext-panel-Panel-cfg-animCollapse'>    /**
129 </span>     * @cfg {Boolean} animCollapse
130      * &lt;code&gt;true&lt;/code&gt; to animate the transition when the panel is collapsed, &lt;code&gt;false&lt;/code&gt; to skip the
131      * animation (defaults to &lt;code&gt;true&lt;/code&gt; if the {@link Ext.fx.Anim} class is available, otherwise &lt;code&gt;false&lt;/code&gt;).
132      * May also be specified as the animation duration in milliseconds.
133      */
134     animCollapse: Ext.enableFx,
135
136 <span id='Ext-panel-Panel-cfg-minButtonWidth'>    /**
137 </span>     * @cfg {Number} minButtonWidth
138      * Minimum width of all footer toolbar buttons in pixels (defaults to &lt;tt&gt;75&lt;/tt&gt;). If set, this will
139      * be used as the default value for the &lt;tt&gt;{@link Ext.button.Button#minWidth}&lt;/tt&gt; config of
140      * each Button added to the &lt;b&gt;footer toolbar&lt;/b&gt; via the {@link #fbar} or {@link #buttons} configurations.
141      * It will be ignored for buttons that have a minWidth configured some other way, e.g. in their own config
142      * object or via the {@link Ext.container.Container#config-defaults defaults} of their parent container.
143      */
144     minButtonWidth: 75,
145
146 <span id='Ext-panel-Panel-cfg-collapsed'>    /**
147 </span>     * @cfg {Boolean} collapsed
148      * &lt;code&gt;true&lt;/code&gt; to render the panel collapsed, &lt;code&gt;false&lt;/code&gt; to render it expanded (defaults to
149      * &lt;code&gt;false&lt;/code&gt;).
150      */
151     collapsed: false,
152
153 <span id='Ext-panel-Panel-cfg-collapseFirst'>    /**
154 </span>     * @cfg {Boolean} collapseFirst
155      * &lt;code&gt;true&lt;/code&gt; to make sure the collapse/expand toggle button always renders first (to the left of)
156      * any other tools in the panel&amp;#39;s title bar, &lt;code&gt;false&lt;/code&gt; to render it last (defaults to &lt;code&gt;true&lt;/code&gt;).
157      */
158     collapseFirst: true,
159
160 <span id='Ext-panel-Panel-cfg-hideCollapseTool'>    /**
161 </span>     * @cfg {Boolean} hideCollapseTool
162      * &lt;code&gt;true&lt;/code&gt; to hide the expand/collapse toggle button when &lt;code&gt;{@link #collapsible} == true&lt;/code&gt;,
163      * &lt;code&gt;false&lt;/code&gt; to display it (defaults to &lt;code&gt;false&lt;/code&gt;).
164      */
165     hideCollapseTool: false,
166
167 <span id='Ext-panel-Panel-cfg-titleCollapse'>    /**
168 </span>     * @cfg {Boolean} titleCollapse
169      * &lt;code&gt;true&lt;/code&gt; to allow expanding and collapsing the panel (when &lt;code&gt;{@link #collapsible} = true&lt;/code&gt;)
170      * by clicking anywhere in the header bar, &lt;code&gt;false&lt;/code&gt;) to allow it only by clicking to tool button
171      * (defaults to &lt;code&gt;false&lt;/code&gt;)).
172      */
173     titleCollapse: false,
174
175 <span id='Ext-panel-Panel-cfg-collapseMode'>    /**
176 </span>     * @cfg {String} collapseMode
177      * &lt;p&gt;&lt;b&gt;Important: this config is only effective for {@link #collapsible} Panels which are direct child items of a {@link Ext.layout.container.Border border layout}.&lt;/b&gt;&lt;/p&gt;
178      * &lt;p&gt;When &lt;i&gt;not&lt;/i&gt; a direct child item of a {@link Ext.layout.container.Border border layout}, then the Panel&amp;#39;s header remains visible, and the body is collapsed to zero dimensions.
179      * If the Panel has no header, then a new header (orientated correctly depending on the {@link #collapseDirection}) will be inserted to show a the title and a re-expand tool.&lt;/p&gt;
180      * &lt;p&gt;When a child item of a {@link Ext.layout.container.Border border layout}, this config has two options:
181      * &lt;div class=&quot;mdetail-params&quot;&gt;&lt;ul&gt;
182      * &lt;li&gt;&lt;b&gt;&lt;code&gt;undefined/omitted&lt;/code&gt;&lt;/b&gt;&lt;div class=&quot;sub-desc&quot;&gt;When collapsed, a placeholder {@link Ext.panel.Header Header} is injected into the layout to represent the Panel
183      * and to provide a UI with a Tool to allow the user to re-expand the Panel.&lt;/div&gt;&lt;/li&gt;
184      * &lt;li&gt;&lt;b&gt;&lt;code&gt;header&lt;/code&gt;&lt;/b&gt; : &lt;div class=&quot;sub-desc&quot;&gt;The Panel collapses to leave its header visible as when not inside a {@link Ext.layout.container.Border border layout}.&lt;/div&gt;&lt;/li&gt;
185      * &lt;/ul&gt;&lt;/div&gt;&lt;/p&gt;
186      */
187
188 <span id='Ext-panel-Panel-cfg-placeholder'>    /**
189 </span>     * @cfg {Mixed} placeholder
190      * &lt;p&gt;&lt;b&gt;Important: This config is only effective for {@link #collapsible} Panels which are direct child items of a {@link Ext.layout.container.Border border layout}
191      * when not using the &lt;code&gt;'header'&lt;/code&gt; {@link #collapseMode}.&lt;/b&gt;&lt;/p&gt;
192      * &lt;p&gt;&lt;b&gt;Optional.&lt;/b&gt; A Component (or config object for a Component) to show in place of this Panel when this Panel is collapsed by a
193      * {@link Ext.layout.container.Border border layout}. Defaults to a generated {@link Ext.panel.Header Header}
194      * containing a {@link Ext.panel.Tool Tool} to re-expand the Panel.&lt;/p&gt;
195      */
196
197 <span id='Ext-panel-Panel-cfg-floatable'>    /**
198 </span>     * @cfg {Boolean} floatable
199      * &lt;p&gt;&lt;b&gt;Important: This config is only effective for {@link #collapsible} Panels which are direct child items of a {@link Ext.layout.container.Border border layout}.&lt;/b&gt;&lt;/p&gt;
200      * &lt;tt&gt;true&lt;/tt&gt; to allow clicking a collapsed Panel&amp;#39;s {@link #placeholder} to display the Panel floated
201      * above the layout, &lt;tt&gt;false&lt;/tt&gt; to force the user to fully expand a collapsed region by
202      * clicking the expand button to see it again (defaults to &lt;tt&gt;true&lt;/tt&gt;).
203      */
204     floatable: true,
205     
206 <span id='Ext-panel-Panel-cfg-overlapHeader'>    /**
207 </span>     * @cfg {Mixed} overlapHeader
208      * True to overlap the header in a panel over the framing of the panel itself. This is needed when frame:true (and is done automatically for you). Otherwise it is undefined.
209      * If you manually add rounded corners to a panel header which does not have frame:true, this will need to be set to true.
210      */
211     
212 <span id='Ext-panel-Panel-cfg-collapsible'>    /**
213 </span>     * @cfg {Boolean} collapsible
214      * &lt;p&gt;True to make the panel collapsible and have an expand/collapse toggle Tool added into
215      * the header tool button area. False to keep the panel sized either statically, or by an owning layout manager, with no toggle Tool (defaults to false).&lt;/p&gt;
216      * See {@link #collapseMode} and {@link #collapseDirection}
217      */
218     collapsible: false,
219
220 <span id='Ext-panel-Panel-cfg-collapseDirection'>    /**
221 </span>     * @cfg {Boolean} collapseDirection
222      * &lt;p&gt;The direction to collapse the Panel when the toggle button is clicked.&lt;/p&gt;
223      * &lt;p&gt;Defaults to the {@link #headerPosition}&lt;/p&gt;
224      * &lt;p&gt;&lt;b&gt;Important: This config is &lt;u&gt;ignored&lt;/u&gt; for {@link #collapsible} Panels which are direct child items of a {@link Ext.layout.container.Border border layout}.&lt;/b&gt;&lt;/p&gt;
225      * &lt;p&gt;Specify as &lt;code&gt;'top'&lt;/code&gt;, &lt;code&gt;'bottom'&lt;/code&gt;, &lt;code&gt;'left'&lt;/code&gt; or &lt;code&gt;'right'&lt;/code&gt;.&lt;/p&gt;
226      */
227
228 <span id='Ext-panel-Panel-cfg-closable'>    /**
229 </span>     * @cfg {Boolean} closable
230      * &lt;p&gt;True to display the 'close' tool button and allow the user to close the window, false to
231      * hide the button and disallow closing the window (defaults to &lt;code&gt;false&lt;/code&gt;).&lt;/p&gt;
232      * &lt;p&gt;By default, when close is requested by clicking the close button in the header, the {@link #close}
233      * method will be called. This will &lt;i&gt;{@link Ext.Component#destroy destroy}&lt;/i&gt; the Panel and its content
234      * meaning that it may not be reused.&lt;/p&gt;
235      * &lt;p&gt;To make closing a Panel &lt;i&gt;hide&lt;/i&gt; the Panel so that it may be reused, set
236      * {@link #closeAction} to 'hide'.&lt;/p&gt;
237      */
238     closable: false,
239
240 <span id='Ext-panel-Panel-cfg-closeAction'>    /**
241 </span>     * @cfg {String} closeAction
242      * &lt;p&gt;The action to take when the close header tool is clicked:
243      * &lt;div class=&quot;mdetail-params&quot;&gt;&lt;ul&gt;
244      * &lt;li&gt;&lt;b&gt;&lt;code&gt;'{@link #destroy}'&lt;/code&gt;&lt;/b&gt; : &lt;b&gt;Default&lt;/b&gt;&lt;div class=&quot;sub-desc&quot;&gt;
245      * {@link #destroy remove} the window from the DOM and {@link Ext.Component#destroy destroy}
246      * it and all descendant Components. The window will &lt;b&gt;not&lt;/b&gt; be available to be
247      * redisplayed via the {@link #show} method.
248      * &lt;/div&gt;&lt;/li&gt;
249      * &lt;li&gt;&lt;b&gt;&lt;code&gt;'{@link #hide}'&lt;/code&gt;&lt;/b&gt; : &lt;div class=&quot;sub-desc&quot;&gt;
250      * {@link #hide} the window by setting visibility to hidden and applying negative offsets.
251      * The window will be available to be redisplayed via the {@link #show} method.
252      * &lt;/div&gt;&lt;/li&gt;
253      * &lt;/ul&gt;&lt;/div&gt;
254      * &lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; This behavior has changed! setting *does* affect the {@link #close} method
255      * which will invoke the approriate closeAction.
256      */
257     closeAction: 'destroy',
258
259 <span id='Ext-panel-Panel-cfg-dockedItems'>    /**
260 </span>     * @cfg {Object/Array} dockedItems
261      * A component or series of components to be added as docked items to this panel.
262      * The docked items can be docked to either the top, right, left or bottom of a panel.
263      * This is typically used for things like toolbars or tab bars:
264      * &lt;pre&gt;&lt;code&gt;
265 var panel = new Ext.panel.Panel({
266     dockedItems: [{
267         xtype: 'toolbar',
268         dock: 'top',
269         items: [{
270             text: 'Docked to the top'
271         }]
272     }]
273 });&lt;/pre&gt;&lt;/code&gt;
274      */
275
276 <span id='Ext-panel-Panel-cfg-preventHeader'>    /**
277 </span>      * @cfg {Boolean} preventHeader Prevent a Header from being created and shown. Defaults to false.
278       */
279     preventHeader: false,
280
281 <span id='Ext-panel-Panel-cfg-headerPosition'>     /**
282 </span>      * @cfg {String} headerPosition Specify as &lt;code&gt;'top'&lt;/code&gt;, &lt;code&gt;'bottom'&lt;/code&gt;, &lt;code&gt;'left'&lt;/code&gt; or &lt;code&gt;'right'&lt;/code&gt;. Defaults to &lt;code&gt;'top'&lt;/code&gt;.
283       */
284     headerPosition: 'top',
285
286 <span id='Ext-panel-Panel-cfg-frame'>     /**
287 </span>     * @cfg {Boolean} frame
288      * True to apply a frame to the panel.
289      */
290     frame: false,
291
292 <span id='Ext-panel-Panel-cfg-frameHeader'>    /**
293 </span>     * @cfg {Boolean} frameHeader
294      * True to apply a frame to the panel panels header (if 'frame' is true).
295      */
296     frameHeader: true,
297
298 <span id='Ext-panel-Panel-cfg-tools'>    /**
299 </span>     * @cfg {Array} tools
300      * An array of {@link Ext.panel.Tool} configs/instances to be added to the header tool area. The tools are stored as child
301      * components of the header container. They can be accessed using {@link #down} and {#query}, as well as the other
302      * component methods. The toggle tool is automatically created if {@link #collapsible} is set to true.
303      * &lt;p&gt;Note that, apart from the toggle tool which is provided when a panel is collapsible, these
304      * tools only provide the visual button. Any required functionality must be provided by adding
305      * handlers that implement the necessary behavior.&lt;/p&gt;
306      * &lt;p&gt;Example usage:&lt;/p&gt;
307      * &lt;pre&gt;&lt;code&gt;
308 tools:[{
309     type:'refresh',
310     qtip: 'Refresh form Data',
311     // hidden:true,
312     handler: function(event, toolEl, panel){
313         // refresh logic
314     }
315 },
316 {
317     type:'help',
318     qtip: 'Get Help',
319     handler: function(event, toolEl, panel){
320         // show help here
321     }
322 }]
323 &lt;/code&gt;&lt;/pre&gt;
324      */
325
326
327     initComponent: function() {
328         var me = this,
329             cls;
330
331         me.addEvents(
332 <span id='Ext-panel-Panel-event-titlechange'>        /**
333 </span>         * @event titlechange
334          * Fires after the Panel title has been set or changed.
335          * @param {Ext.panel.Panel} p the Panel which has been resized.
336          * @param {String} newTitle The new title.
337          * @param {String} oldTitle The previous panel title.
338          */
339             'titlechange',
340 <span id='Ext-panel-Panel-event-iconchange'>        /**
341 </span>         * @event iconchange
342          * Fires after the Panel iconCls has been set or changed.
343          * @param {Ext.panel.Panel} p the Panel which has been resized.
344          * @param {String} newIconCls The new iconCls.
345          * @param {String} oldIconCls The previous panel iconCls.
346          */
347             'iconchange'
348         );
349
350         if (me.unstyled) {
351             me.setUI('plain');
352         }
353
354         if (me.frame) {
355             me.setUI('default-framed');
356         }
357
358         me.callParent();
359
360         me.collapseDirection = me.collapseDirection || me.headerPosition || Ext.Component.DIRECTION_TOP;
361
362         // Backwards compatibility
363         me.bridgeToolbars();
364     },
365
366     setBorder: function(border) {
367         // var me     = this,
368         //     method = (border === false || border === 0) ? 'addClsWithUI' : 'removeClsWithUI';
369         // 
370         // me.callParent(arguments);
371         // 
372         // if (me.collapsed) {
373         //     me[method](me.collapsedCls + '-noborder');
374         // }
375         // 
376         // if (me.header) {
377         //     me.header.setBorder(border);
378         //     if (me.collapsed) {
379         //         me.header[method](me.collapsedCls + '-noborder');
380         //     }
381         // }
382         
383         this.callParent(arguments);
384     },
385
386     beforeDestroy: function() {
387         Ext.destroy(
388             this.ghostPanel,
389             this.dd
390         );
391         this.callParent();
392     },
393
394     initAria: function() {
395         this.callParent();
396         this.initHeaderAria();
397     },
398
399     initHeaderAria: function() {
400         var me = this,
401             el = me.el,
402             header = me.header;
403         if (el &amp;&amp; header) {
404             el.dom.setAttribute('aria-labelledby', header.titleCmp.id);
405         }
406     },
407
408     getHeader: function() {
409         return this.header;
410     },
411
412 <span id='Ext-panel-Panel-method-setTitle'>    /**
413 </span>     * Set a title for the panel&amp;#39;s header. See {@link Ext.panel.Header#title}.
414      * @param {String} newTitle
415      */
416     setTitle: function(newTitle) {
417         var me = this,
418         oldTitle = this.title;
419
420         me.title = newTitle;
421         if (me.header) {
422             me.header.setTitle(newTitle);
423         } else {
424             me.updateHeader();
425         }
426
427         if (me.reExpander) {
428             me.reExpander.setTitle(newTitle);
429         }
430         me.fireEvent('titlechange', me, newTitle, oldTitle);
431     },
432
433 <span id='Ext-panel-Panel-method-setIconCls'>    /**
434 </span>     * Set the iconCls for the panel&amp;#39;s header. See {@link Ext.panel.Header#iconCls}.
435      * @param {String} newIconCls
436      */
437     setIconCls: function(newIconCls) {
438         var me = this,
439             oldIconCls = me.iconCls;
440
441         me.iconCls = newIconCls;
442         var header = me.header;
443         if (header) {
444             header.setIconCls(newIconCls);
445         }
446         me.fireEvent('iconchange', me, newIconCls, oldIconCls);
447     },
448
449     bridgeToolbars: function() {
450         var me = this,
451             fbar,
452             fbarDefaults,
453             minButtonWidth = me.minButtonWidth;
454
455         function initToolbar (toolbar, pos) {
456             if (Ext.isArray(toolbar)) {
457                 toolbar = {
458                     xtype: 'toolbar',
459                     items: toolbar
460                 };
461             }
462             else if (!toolbar.xtype) {
463                 toolbar.xtype = 'toolbar';
464             }
465             toolbar.dock = pos;
466             if (pos == 'left' || pos == 'right') {
467                 toolbar.vertical = true;
468             }
469             return toolbar;
470         }
471
472         // Backwards compatibility
473
474 <span id='Ext-panel-Panel-cfg-tbar'>        /**
475 </span>         * @cfg {Object/Array} tbar
476
477 Convenience method. Short for 'Top Bar'.
478
479     tbar: [
480       { xtype: 'button', text: 'Button 1' }
481     ]
482
483 is equivalent to
484
485     dockedItems: [{
486         xtype: 'toolbar',
487         dock: 'top',
488         items: [
489             { xtype: 'button', text: 'Button 1' }
490         ]
491     }]
492
493          * @markdown
494          */
495         if (me.tbar) {
496             me.addDocked(initToolbar(me.tbar, 'top'));
497             me.tbar = null;
498         }
499
500 <span id='Ext-panel-Panel-cfg-bbar'>        /**
501 </span>         * @cfg {Object/Array} bbar
502
503 Convenience method. Short for 'Bottom Bar'.
504
505     bbar: [
506       { xtype: 'button', text: 'Button 1' }
507     ]
508
509 is equivalent to
510
511     dockedItems: [{
512         xtype: 'toolbar',
513         dock: 'bottom',
514         items: [
515             { xtype: 'button', text: 'Button 1' }
516         ]
517     }]
518
519          * @markdown
520          */
521         if (me.bbar) {
522             me.addDocked(initToolbar(me.bbar, 'bottom'));
523             me.bbar = null;
524         }
525
526 <span id='Ext-panel-Panel-cfg-buttons'>        /**
527 </span>         * @cfg {Object/Array} buttons
528
529 Convenience method used for adding buttons docked to the bottom right of the panel. This is a
530 synonym for the {@link #fbar} config.
531
532     buttons: [
533       { text: 'Button 1' }
534     ]
535
536 is equivalent to
537
538     dockedItems: [{
539         xtype: 'toolbar',
540         dock: 'bottom',
541         defaults: {minWidth: {@link #minButtonWidth}},
542         items: [
543             { xtype: 'component', flex: 1 },
544             { xtype: 'button', text: 'Button 1' }
545         ]
546     }]
547
548 The {@link #minButtonWidth} is used as the default {@link Ext.button.Button#minWidth minWidth} for
549 each of the buttons in the buttons toolbar.
550
551          * @markdown
552          */
553         if (me.buttons) {
554             me.fbar = me.buttons;
555             me.buttons = null;
556         }
557
558 <span id='Ext-panel-Panel-cfg-fbar'>        /**
559 </span>         * @cfg {Object/Array} fbar
560
561 Convenience method used for adding items to the bottom right of the panel. Short for Footer Bar.
562
563     fbar: [
564       { type: 'button', text: 'Button 1' }
565     ]
566
567 is equivalent to
568
569     dockedItems: [{
570         xtype: 'toolbar',
571         dock: 'bottom',
572         defaults: {minWidth: {@link #minButtonWidth}},
573         items: [
574             { xtype: 'component', flex: 1 },
575             { xtype: 'button', text: 'Button 1' }
576         ]
577     }]
578
579 The {@link #minButtonWidth} is used as the default {@link Ext.button.Button#minWidth minWidth} for
580 each of the buttons in the fbar.
581
582          * @markdown
583          */
584         if (me.fbar) {
585             fbar = initToolbar(me.fbar, 'bottom');
586             fbar.ui = 'footer';
587
588             // Apply the minButtonWidth config to buttons in the toolbar
589             if (minButtonWidth) {
590                 fbarDefaults = fbar.defaults;
591                 fbar.defaults = function(config) {
592                     var defaults = fbarDefaults || {};
593                     if ((!config.xtype || config.xtype === 'button' || (config.isComponent &amp;&amp; config.isXType('button'))) &amp;&amp;
594                             !('minWidth' in defaults)) {
595                         defaults = Ext.apply({minWidth: minButtonWidth}, defaults);
596                     }
597                     return defaults;
598                 };
599             }
600
601             fbar = me.addDocked(fbar)[0];
602             fbar.insert(0, {
603                 flex: 1,
604                 xtype: 'component',
605                 focusable: false
606             });
607             me.fbar = null;
608         }
609
610 <span id='Ext-panel-Panel-cfg-lbar'>        /**
611 </span>         * @cfg {Object/Array} lbar
612          *
613          * Convenience method. Short for 'Left Bar' (left-docked, vertical toolbar).
614          *
615          *    lbar: [
616          *      { xtype: 'button', text: 'Button 1' }
617          *    ]
618          *
619          * is equivalent to
620          *
621          *    dockedItems: [{
622          *        xtype: 'toolbar',
623          *        dock: 'left',
624          *        items: [
625          *            { xtype: 'button', text: 'Button 1' }
626          *        ]
627          *    }]
628          *
629          * @markdown
630          */
631         if (me.lbar) {
632             me.addDocked(initToolbar(me.lbar, 'left'));
633             me.lbar = null;
634         }
635
636 <span id='Ext-panel-Panel-cfg-rbar'>        /**
637 </span>         * @cfg {Object/Array} rbar
638          *
639          * Convenience method. Short for 'Right Bar' (right-docked, vertical toolbar).
640          *
641          *    rbar: [
642          *      { xtype: 'button', text: 'Button 1' }
643          *    ]
644          *
645          * is equivalent to
646          *
647          *    dockedItems: [{
648          *        xtype: 'toolbar',
649          *        dock: 'right',
650          *        items: [
651          *            { xtype: 'button', text: 'Button 1' }
652          *        ]
653          *    }]
654          *
655          * @markdown
656          */
657         if (me.rbar) {
658             me.addDocked(initToolbar(me.rbar, 'right'));
659             me.rbar = null;
660         }
661     },
662
663 <span id='Ext-panel-Panel-method-initTools'>    /**
664 </span>     * @private
665      * Tools are a Panel-specific capabilty.
666      * Panel uses initTools. Subclasses may contribute tools by implementing addTools.
667      */
668     initTools: function() {
669         var me = this;
670
671         me.tools = me.tools || [];
672
673         // Add a collapse tool unless configured to not show a collapse tool
674         // or to not even show a header.
675         if (me.collapsible &amp;&amp; !(me.hideCollapseTool || me.header === false)) {
676             me.collapseDirection = me.collapseDirection || me.headerPosition || 'top';
677             me.collapseTool = me.expandTool = me.createComponent({
678                 xtype: 'tool',
679                 type: 'collapse-' + me.collapseDirection,
680                 expandType: me.getOppositeDirection(me.collapseDirection),
681                 handler: me.toggleCollapse,
682                 scope: me
683             });
684
685             // Prepend collapse tool is configured to do so.
686             if (me.collapseFirst) {
687                 me.tools.unshift(me.collapseTool);
688             }
689         }
690
691         // Add subclass-specific tools.
692         me.addTools();
693
694         // Make Panel closable.
695         if (me.closable) {
696             me.addClsWithUI('closable');
697             me.addTool({
698                 type: 'close',
699                 handler: Ext.Function.bind(me.close, this, [])
700             });
701         }
702
703         // Append collapse tool if needed.
704         if (me.collapseTool &amp;&amp; !me.collapseFirst) {
705             me.tools.push(me.collapseTool);
706         }
707     },
708
709 <span id='Ext-panel-Panel-property-addTools'>    /**
710 </span>     * @private
711      * Template method to be implemented in subclasses to add their tools after the collapsible tool.
712      */
713     addTools: Ext.emptyFn,
714
715 <span id='Ext-panel-Panel-method-close'>    /**
716 </span>     * &lt;p&gt;Closes the Panel. By default, this method, removes it from the DOM, {@link Ext.Component#destroy destroy}s
717      * the Panel object and all its descendant Components. The {@link #beforeclose beforeclose}
718      * event is fired before the close happens and will cancel the close action if it returns false.&lt;p&gt;
719      * &lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; This method is not affected by the {@link #closeAction} setting which
720      * only affects the action triggered when clicking the {@link #closable 'close' tool in the header}.
721      * To hide the Panel without destroying it, call {@link #hide}.&lt;/p&gt;
722      */
723     close: function() {
724         if (this.fireEvent('beforeclose', this) !== false) {
725             this.doClose();
726         }
727     },
728
729     // private
730     doClose: function() {
731         this.fireEvent('close', this);
732         this[this.closeAction]();
733     },
734
735     onRender: function(ct, position) {
736         var me = this,
737             topContainer;
738
739         // Add class-specific header tools.
740         // Panel adds collapsible and closable.
741         me.initTools();
742
743         // Dock the header/title
744         me.updateHeader();
745
746         // If initially collapsed, collapsed flag must indicate true current state at this point.
747         // Do collapse after the first time the Panel's structure has been laid out.
748         if (me.collapsed) {
749             me.collapsed = false;
750             topContainer = me.findLayoutController();
751             if (!me.hidden &amp;&amp; topContainer) {
752                 topContainer.on({
753                     afterlayout: function() {
754                         me.collapse(null, false, true);
755                     },
756                     single: true
757                 });
758             } else {
759                 me.afterComponentLayout = function() {
760                     delete me.afterComponentLayout;
761                     Ext.getClass(me).prototype.afterComponentLayout.apply(me, arguments);
762                     me.collapse(null, false, true);
763                 };
764             }
765         }
766
767         // Call to super after adding the header, to prevent an unnecessary re-layout
768         me.callParent(arguments);
769     },
770
771 <span id='Ext-panel-Panel-method-updateHeader'>    /**
772 </span>     * Create, hide, or show the header component as appropriate based on the current config.
773      * @private
774      * @param {Boolean} force True to force the the header to be created
775      */
776     updateHeader: function(force) {
777         var me = this,
778             header = me.header,
779             title = me.title,
780             tools = me.tools;
781
782         if (!me.preventHeader &amp;&amp; (force || title || (tools &amp;&amp; tools.length))) {
783             if (!header) {
784                 header = me.header = Ext.create('Ext.panel.Header', {
785                     title       : title,
786                     orientation : (me.headerPosition == 'left' || me.headerPosition == 'right') ? 'vertical' : 'horizontal',
787                     dock        : me.headerPosition || 'top',
788                     textCls     : me.headerTextCls,
789                     iconCls     : me.iconCls,
790                     baseCls     : me.baseCls + '-header',
791                     tools       : tools,
792                     ui          : me.ui,
793                     indicateDrag: me.draggable,
794                     border      : me.border,
795                     frame       : me.frame &amp;&amp; me.frameHeader,
796                     ignoreParentFrame : me.frame || me.overlapHeader,
797                     ignoreBorderManagement: me.frame || me.ignoreHeaderBorderManagement,
798                     listeners   : me.collapsible &amp;&amp; me.titleCollapse ? {
799                         click: me.toggleCollapse,
800                         scope: me
801                     } : null
802                 });
803                 me.addDocked(header, 0);
804
805                 // Reference the Header's tool array.
806                 // Header injects named references.
807                 me.tools = header.tools;
808             }
809             header.show();
810             me.initHeaderAria();
811         } else if (header) {
812             header.hide();
813         }
814     },
815
816     // inherit docs
817     setUI: function(ui) {
818         var me = this;
819
820         me.callParent(arguments);
821
822         if (me.header) {
823             me.header.setUI(ui);
824         }
825     },
826
827     // private
828     getContentTarget: function() {
829         return this.body;
830     },
831
832     getTargetEl: function() {
833         return this.body || this.frameBody || this.el;
834     },
835
836     addTool: function(tool) {
837         this.tools.push(tool);
838         var header = this.header;
839         if (header) {
840             header.addTool(tool);
841         }
842         this.updateHeader();
843     },
844
845     getOppositeDirection: function(d) {
846         var c = Ext.Component;
847         switch (d) {
848             case c.DIRECTION_TOP:
849                 return c.DIRECTION_BOTTOM;
850             case c.DIRECTION_RIGHT:
851                 return c.DIRECTION_LEFT;
852             case c.DIRECTION_BOTTOM:
853                 return c.DIRECTION_TOP;
854             case c.DIRECTION_LEFT:
855                 return c.DIRECTION_RIGHT;
856         }
857     },
858
859 <span id='Ext-panel-Panel-method-collapse'>    /**
860 </span>     * Collapses the panel body so that the body becomes hidden. Docked Components parallel to the
861      * border towards which the collapse takes place will remain visible.  Fires the {@link #beforecollapse} event which will
862      * cancel the collapse action if it returns false.
863      * @param {Number} direction. The direction to collapse towards. Must be one of&lt;ul&gt;
864      * &lt;li&gt;Ext.Component.DIRECTION_TOP&lt;/li&gt;
865      * &lt;li&gt;Ext.Component.DIRECTION_RIGHT&lt;/li&gt;
866      * &lt;li&gt;Ext.Component.DIRECTION_BOTTOM&lt;/li&gt;
867      * &lt;li&gt;Ext.Component.DIRECTION_LEFT&lt;/li&gt;&lt;/ul&gt;
868      * @param {Boolean} animate True to animate the transition, else false (defaults to the value of the
869      * {@link #animCollapse} panel config)
870      * @return {Ext.panel.Panel} this
871      */
872     collapse: function(direction, animate, /* private - passed if called at render time */ internal) {
873         var me = this,
874             c = Ext.Component,
875             height = me.getHeight(),
876             width = me.getWidth(),
877             frameInfo,
878             newSize = 0,
879             dockedItems = me.dockedItems.items,
880             dockedItemCount = dockedItems.length,
881             i = 0,
882             comp,
883             pos,
884             anim = {
885                 from: {
886                     height: height,
887                     width: width
888                 },
889                 to: {
890                     height: height,
891                     width: width
892                 },
893                 listeners: {
894                     afteranimate: me.afterCollapse,
895                     scope: me
896                 },
897                 duration: Ext.Number.from(animate, Ext.fx.Anim.prototype.duration)
898             },
899             reExpander,
900             reExpanderOrientation,
901             reExpanderDock,
902             getDimension,
903             setDimension,
904             collapseDimension;
905
906         if (!direction) {
907             direction = me.collapseDirection;
908         }
909
910         // If internal (Called because of initial collapsed state), then no animation, and no events.
911         if (internal) {
912             animate = false;
913         } else if (me.collapsed || me.fireEvent('beforecollapse', me, direction, animate) === false) {
914             return false;
915         }
916
917         reExpanderDock = direction;
918         me.expandDirection = me.getOppositeDirection(direction);
919
920         // Track docked items which we hide during collapsed state
921         me.hiddenDocked = [];
922
923         switch (direction) {
924             case c.DIRECTION_TOP:
925             case c.DIRECTION_BOTTOM:
926                 me.expandedSize = me.getHeight();
927                 reExpanderOrientation = 'horizontal';
928                 collapseDimension = 'height';
929                 getDimension = 'getHeight';
930                 setDimension = 'setHeight';
931
932                 // Collect the height of the visible header.
933                 // Hide all docked items except the header.
934                 // Hide *ALL* docked items if we're going to end up hiding the whole Panel anyway
935                 for (; i &lt; dockedItemCount; i++) {
936                     comp = dockedItems[i];
937                     if (comp.isVisible()) {
938                         if (comp.isHeader &amp;&amp; (!comp.dock || comp.dock == 'top' || comp.dock == 'bottom')) {
939                             reExpander = comp;
940                         } else {
941                             me.hiddenDocked.push(comp);
942                         }
943                     }
944                 }
945
946                 if (direction == Ext.Component.DIRECTION_BOTTOM) {
947                     pos = me.getPosition()[1] - Ext.fly(me.el.dom.offsetParent).getRegion().top;
948                     anim.from.top = pos;
949                 }
950                 break;
951
952             case c.DIRECTION_LEFT:
953             case c.DIRECTION_RIGHT:
954                 me.expandedSize = me.getWidth();
955                 reExpanderOrientation = 'vertical';
956                 collapseDimension = 'width';
957                 getDimension = 'getWidth';
958                 setDimension = 'setWidth';
959
960                 // Collect the height of the visible header.
961                 // Hide all docked items except the header.
962                 // Hide *ALL* docked items if we're going to end up hiding the whole Panel anyway
963                 for (; i &lt; dockedItemCount; i++) {
964                     comp = dockedItems[i];
965                     if (comp.isVisible()) {
966                         if (comp.isHeader &amp;&amp; (comp.dock == 'left' || comp.dock == 'right')) {
967                             reExpander = comp;
968                         } else {
969                             me.hiddenDocked.push(comp);
970                         }
971                     }
972                 }
973
974                 if (direction == Ext.Component.DIRECTION_RIGHT) {
975                     pos = me.getPosition()[0] - Ext.fly(me.el.dom.offsetParent).getRegion().left;
976                     anim.from.left = pos;
977                 }
978                 break;
979
980             default:
981                 throw('Panel collapse must be passed a valid Component collapse direction');
982         }
983
984         // No scrollbars when we shrink this Panel
985         // And no laying out of any children... we're effectively *hiding* the body
986         me.setAutoScroll(false);
987         me.suspendLayout = true;
988         me.body.setVisibilityMode(Ext.core.Element.DISPLAY);
989
990         // Disable toggle tool during animated collapse
991         if (animate &amp;&amp; me.collapseTool) {
992             me.collapseTool.disable();
993         }
994
995         // Add the collapsed class now, so that collapsed CSS rules are applied before measurements are taken.
996         me.addClsWithUI(me.collapsedCls);
997         // if (me.border === false) {
998         //     me.addClsWithUI(me.collapsedCls + '-noborder');
999         // }
1000
1001         // We found a header: Measure it to find the collapse-to size.
1002         if (reExpander) {
1003             //we must add the collapsed cls to the header and then remove to get the proper height
1004             reExpander.addClsWithUI(me.collapsedCls);
1005             reExpander.addClsWithUI(me.collapsedCls + '-' + reExpander.dock);
1006             if (me.border &amp;&amp; (!me.frame || (me.frame &amp;&amp; Ext.supports.CSS3BorderRadius))) {
1007                 reExpander.addClsWithUI(me.collapsedCls + '-border-' + reExpander.dock);
1008             }
1009
1010             frameInfo = reExpander.getFrameInfo();
1011                         
1012             //get the size
1013             newSize = reExpander[getDimension]() + (frameInfo ? frameInfo[direction] : 0);
1014
1015             //and remove
1016             reExpander.removeClsWithUI(me.collapsedCls);
1017             reExpander.removeClsWithUI(me.collapsedCls + '-' + reExpander.dock);              
1018             if (me.border &amp;&amp; (!me.frame || (me.frame &amp;&amp; Ext.supports.CSS3BorderRadius))) {
1019                 reExpander.removeClsWithUI(me.collapsedCls + '-border-' + reExpander.dock);
1020             }
1021         }
1022         // No header: Render and insert a temporary one, and then measure it.
1023         else {
1024             reExpander = {
1025                 hideMode: 'offsets',
1026                 temporary: true,
1027                 title: me.title,
1028                 orientation: reExpanderOrientation,
1029                 dock: reExpanderDock,
1030                 textCls: me.headerTextCls,
1031                 iconCls: me.iconCls,
1032                 baseCls: me.baseCls + '-header',
1033                 ui: me.ui,
1034                 frame: me.frame &amp;&amp; me.frameHeader,
1035                 ignoreParentFrame: me.frame || me.overlapHeader,
1036                 indicateDrag: me.draggable,
1037                 cls: me.baseCls + '-collapsed-placeholder ' + ' ' + Ext.baseCSSPrefix + 'docked ' + me.baseCls + '-' + me.ui + '-collapsed',
1038                 renderTo: me.el
1039             };
1040             if (!me.hideCollapseTool) {
1041                 reExpander[(reExpander.orientation == 'horizontal') ? 'tools' : 'items'] = [{
1042                     xtype: 'tool',
1043                     type: 'expand-' + me.expandDirection,
1044                     handler: me.toggleCollapse,
1045                     scope: me
1046                 }];
1047             }
1048
1049             // Capture the size of the re-expander.
1050             // For vertical headers in IE6 and IE7, this will be sized by a CSS rule in _panel.scss
1051             reExpander = me.reExpander = Ext.create('Ext.panel.Header', reExpander);
1052             newSize = reExpander[getDimension]() + ((reExpander.frame) ? reExpander.frameSize[direction] : 0);
1053             reExpander.hide();
1054
1055             // Insert the new docked item
1056             me.insertDocked(0, reExpander);
1057         }
1058
1059         me.reExpander = reExpander;
1060         me.reExpander.addClsWithUI(me.collapsedCls);
1061         me.reExpander.addClsWithUI(me.collapsedCls + '-' + reExpander.dock);
1062         if (me.border &amp;&amp; (!me.frame || (me.frame &amp;&amp; Ext.supports.CSS3BorderRadius))) {
1063             me.reExpander.addClsWithUI(me.collapsedCls + '-border-' + me.reExpander.dock);
1064         }
1065
1066         // If collapsing right or down, we'll be also animating the left or top.
1067         if (direction == Ext.Component.DIRECTION_RIGHT) {
1068             anim.to.left = pos + (width - newSize);
1069         } else if (direction == Ext.Component.DIRECTION_BOTTOM) {
1070             anim.to.top = pos + (height - newSize);
1071         }
1072
1073         // Animate to the new size
1074         anim.to[collapseDimension] = newSize;
1075
1076         // Remove any flex config before we attempt to collapse.
1077         me.savedFlex = me.flex;
1078         me.savedMinWidth = me.minWidth;
1079         me.savedMinHeight = me.minHeight;
1080         me.minWidth = 0;
1081         me.minHeight = 0;
1082         delete me.flex;
1083
1084         if (animate) {
1085             me.animate(anim);
1086         } else {
1087             // EXTJSIV-1937 (would like to use setCalculateSize)
1088             // save width/height here, expand puts them back
1089             me.uncollapsedSize = { width: me.width, height: me.height };
1090
1091             me.setSize(anim.to.width, anim.to.height);
1092             if (Ext.isDefined(anim.to.left) || Ext.isDefined(anim.to.top)) {
1093                 me.setPosition(anim.to.left, anim.to.top);
1094             }
1095             me.afterCollapse(false, internal);
1096         }
1097         return me;
1098     },
1099
1100     afterCollapse: function(animated, internal) {
1101         var me = this,
1102             i = 0,
1103             l = me.hiddenDocked.length;
1104
1105         me.minWidth = me.savedMinWidth;
1106         me.minHeight = me.savedMinHeight;
1107
1108         me.body.hide();
1109         for (; i &lt; l; i++) {
1110             me.hiddenDocked[i].hide();
1111         }
1112         if (me.reExpander) {
1113             me.reExpander.updateFrame();
1114             me.reExpander.show();
1115         }
1116         me.collapsed = true;
1117
1118         if (!internal) {
1119             me.doComponentLayout();
1120         }
1121
1122         if (me.resizer) {
1123             me.resizer.disable();
1124         }
1125
1126         // If me Panel was configured with a collapse tool in its header, flip it's type
1127         if (me.collapseTool) {
1128             me.collapseTool.setType('expand-' + me.expandDirection);
1129         }
1130         if (!internal) {
1131             me.fireEvent('collapse', me);
1132         }
1133
1134         // Re-enable the toggle tool after an animated collapse
1135         if (animated &amp;&amp; me.collapseTool) {
1136             me.collapseTool.enable();
1137         }
1138     },
1139
1140 <span id='Ext-panel-Panel-method-expand'>    /**
1141 </span>     * Expands the panel body so that it becomes visible.  Fires the {@link #beforeexpand} event which will
1142      * cancel the expand action if it returns false.
1143      * @param {Boolean} animate True to animate the transition, else false (defaults to the value of the
1144      * {@link #animCollapse} panel config)
1145      * @return {Ext.panel.Panel} this
1146      */
1147     expand: function(animate) {
1148         if (!this.collapsed || this.fireEvent('beforeexpand', this, animate) === false) {
1149             return false;
1150         }
1151
1152         // EXTJSIV-1937 (would like to use setCalculateSize)
1153         if (this.uncollapsedSize) {
1154             Ext.Object.each(this.uncollapsedSize, function (name, value) {
1155                 if (Ext.isDefined(value)) {
1156                     this[name] = value;
1157                 } else {
1158                     delete this[name];
1159                 }
1160             }, this);
1161             delete this.uncollapsedSize;
1162         }
1163
1164         var me = this,
1165             i = 0,
1166             l = me.hiddenDocked.length,
1167             direction = me.expandDirection,
1168             height = me.getHeight(),
1169             width = me.getWidth(),
1170             pos, anim, satisfyJSLint;
1171
1172         // Disable toggle tool during animated expand
1173         if (animate &amp;&amp; me.collapseTool) {
1174             me.collapseTool.disable();
1175         }
1176
1177         // Show any docked items that we hid on collapse
1178         // And hide the injected reExpander Header
1179         for (; i &lt; l; i++) {
1180             me.hiddenDocked[i].hidden = false;
1181             me.hiddenDocked[i].el.show();
1182         }
1183         if (me.reExpander) {
1184             if (me.reExpander.temporary) {
1185                 me.reExpander.hide();
1186             } else {
1187                 me.reExpander.removeClsWithUI(me.collapsedCls);
1188                 me.reExpander.removeClsWithUI(me.collapsedCls + '-' + me.reExpander.dock);
1189                 if (me.border &amp;&amp; (!me.frame || (me.frame &amp;&amp; Ext.supports.CSS3BorderRadius))) {
1190                     me.reExpander.removeClsWithUI(me.collapsedCls + '-border-' + me.reExpander.dock);
1191                 }
1192                 me.reExpander.updateFrame();
1193             }
1194         }
1195
1196         // If me Panel was configured with a collapse tool in its header, flip it's type
1197         if (me.collapseTool) {
1198             me.collapseTool.setType('collapse-' + me.collapseDirection);
1199         }
1200
1201         // Unset the flag before the potential call to calculateChildBox to calculate our newly flexed size
1202         me.collapsed = false;
1203
1204         // Collapsed means body element was hidden
1205         me.body.show();
1206
1207         // Remove any collapsed styling before any animation begins
1208         me.removeClsWithUI(me.collapsedCls);
1209         // if (me.border === false) {
1210         //     me.removeClsWithUI(me.collapsedCls + '-noborder');
1211         // }
1212
1213         anim = {
1214             to: {
1215             },
1216             from: {
1217                 height: height,
1218                 width: width
1219             },
1220             listeners: {
1221                 afteranimate: me.afterExpand,
1222                 scope: me
1223             }
1224         };
1225
1226         if ((direction == Ext.Component.DIRECTION_TOP) || (direction == Ext.Component.DIRECTION_BOTTOM)) {
1227
1228             // If autoHeight, measure the height now we have shown the body element.
1229             if (me.autoHeight) {
1230                 me.setCalculatedSize(me.width, null);
1231                 anim.to.height = me.getHeight();
1232
1233                 // Must size back down to collapsed for the animation.
1234                 me.setCalculatedSize(me.width, anim.from.height);
1235             }
1236             // If we were flexed, then we can't just restore to the saved size.
1237             // We must restore to the currently correct, flexed size, so we much ask the Box layout what that is.
1238             else if (me.savedFlex) {
1239                 me.flex = me.savedFlex;
1240                 anim.to.height = me.ownerCt.layout.calculateChildBox(me).height;
1241                 delete me.flex;
1242             }
1243             // Else, restore to saved height
1244             else {
1245                 anim.to.height = me.expandedSize;
1246             }
1247
1248             // top needs animating upwards
1249             if (direction == Ext.Component.DIRECTION_TOP) {
1250                 pos = me.getPosition()[1] - Ext.fly(me.el.dom.offsetParent).getRegion().top;
1251                 anim.from.top = pos;
1252                 anim.to.top = pos - (anim.to.height - height);
1253             }
1254         } else if ((direction == Ext.Component.DIRECTION_LEFT) || (direction == Ext.Component.DIRECTION_RIGHT)) {
1255
1256             // If autoWidth, measure the width now we have shown the body element.
1257             if (me.autoWidth) {
1258                 me.setCalculatedSize(null, me.height);
1259                 anim.to.width = me.getWidth();
1260
1261                 // Must size back down to collapsed for the animation.
1262                 me.setCalculatedSize(anim.from.width, me.height);
1263             }
1264             // If we were flexed, then we can't just restore to the saved size.
1265             // We must restore to the currently correct, flexed size, so we much ask the Box layout what that is.
1266             else if (me.savedFlex) {
1267                 me.flex = me.savedFlex;
1268                 anim.to.width = me.ownerCt.layout.calculateChildBox(me).width;
1269                 delete me.flex;
1270             }
1271             // Else, restore to saved width
1272             else {
1273                 anim.to.width = me.expandedSize;
1274             }
1275
1276             // left needs animating leftwards
1277             if (direction == Ext.Component.DIRECTION_LEFT) {
1278                 pos = me.getPosition()[0] - Ext.fly(me.el.dom.offsetParent).getRegion().left;
1279                 anim.from.left = pos;
1280                 anim.to.left = pos - (anim.to.width - width);
1281             }
1282         }
1283
1284         if (animate) {
1285             me.animate(anim);
1286         } else {
1287             me.setSize(anim.to.width, anim.to.height);
1288             if (anim.to.x) {
1289                 me.setLeft(anim.to.x);
1290             }
1291             if (anim.to.y) {
1292                 me.setTop(anim.to.y);
1293             }
1294             me.afterExpand(false);
1295         }
1296
1297         return me;
1298     },
1299
1300     afterExpand: function(animated) {
1301         var me = this;
1302         me.setAutoScroll(me.initialConfig.autoScroll);
1303
1304         // Restored to a calculated flex. Delete the set width and height properties so that flex works from now on.
1305         if (me.savedFlex) {
1306             me.flex = me.savedFlex;
1307             delete me.savedFlex;
1308             delete me.width;
1309             delete me.height;
1310         }
1311
1312         // Reinstate layout out after Panel has re-expanded
1313         delete me.suspendLayout;
1314         if (animated &amp;&amp; me.ownerCt) {
1315             me.ownerCt.doLayout();
1316         }
1317
1318         if (me.resizer) {
1319             me.resizer.enable();
1320         }
1321
1322         me.fireEvent('expand', me);
1323
1324         // Re-enable the toggle tool after an animated expand
1325         if (animated &amp;&amp; me.collapseTool) {
1326             me.collapseTool.enable();
1327         }
1328     },
1329
1330 <span id='Ext-panel-Panel-method-toggleCollapse'>    /**
1331 </span>     * Shortcut for performing an {@link #expand} or {@link #collapse} based on the current state of the panel.
1332      * @return {Ext.panel.Panel} this
1333      */
1334     toggleCollapse: function() {
1335         if (this.collapsed) {
1336             this.expand(this.animCollapse);
1337         } else {
1338             this.collapse(this.collapseDirection, this.animCollapse);
1339         }
1340         return this;
1341     },
1342
1343     // private
1344     getKeyMap : function(){
1345         if(!this.keyMap){
1346             this.keyMap = Ext.create('Ext.util.KeyMap', this.el, this.keys);
1347         }
1348         return this.keyMap;
1349     },
1350
1351     // private
1352     initDraggable : function(){
1353 <span id='Ext-panel-Panel-property-dd'>        /**
1354 </span>         * &lt;p&gt;If this Panel is configured {@link #draggable}, this property will contain
1355          * an instance of {@link Ext.dd.DragSource} which handles dragging the Panel.&lt;/p&gt;
1356          * The developer must provide implementations of the abstract methods of {@link Ext.dd.DragSource}
1357          * in order to supply behaviour for each stage of the drag/drop process. See {@link #draggable}.
1358          * @type Ext.dd.DragSource.
1359          * @property dd
1360          */
1361         this.dd = Ext.create('Ext.panel.DD', this, Ext.isBoolean(this.draggable) ? null : this.draggable);
1362     },
1363
1364     // private - helper function for ghost
1365     ghostTools : function() {
1366         var tools = [],
1367             origTools = this.initialConfig.tools;
1368
1369         if (origTools) {
1370             Ext.each(origTools, function(tool) {
1371                 // Some tools can be full components, and copying them into the ghost
1372                 // actually removes them from the owning panel. You could also potentially
1373                 // end up with duplicate DOM ids as well. To avoid any issues we just make
1374                 // a simple bare-minimum clone of each tool for ghosting purposes.
1375                 tools.push({
1376                     type: tool.type
1377                 });
1378             });
1379         }
1380         else {
1381             tools = [{
1382                 type: 'placeholder'
1383             }];
1384         }
1385         return tools;
1386     },
1387
1388     // private - used for dragging
1389     ghost: function(cls) {
1390         var me = this,
1391             ghostPanel = me.ghostPanel,
1392             box = me.getBox();
1393
1394         if (!ghostPanel) {
1395             ghostPanel = Ext.create('Ext.panel.Panel', {
1396                 renderTo: document.body,
1397                 floating: {
1398                     shadow: false
1399                 },
1400                 frame: Ext.supports.CSS3BorderRadius ? me.frame : false,
1401                 title: me.title,
1402                 overlapHeader: me.overlapHeader,
1403                 headerPosition: me.headerPosition,
1404                 width: me.getWidth(),
1405                 height: me.getHeight(),
1406                 iconCls: me.iconCls,
1407                 baseCls: me.baseCls,
1408                 tools: me.ghostTools(),
1409                 cls: me.baseCls + '-ghost ' + (cls ||'')
1410             });
1411             me.ghostPanel = ghostPanel;
1412         }
1413         ghostPanel.floatParent = me.floatParent;
1414         if (me.floating) {
1415             ghostPanel.setZIndex(Ext.Number.from(me.el.getStyle('zIndex'), 0));
1416         } else {
1417             ghostPanel.toFront();
1418         }
1419         ghostPanel.el.show();
1420         ghostPanel.setPosition(box.x, box.y);
1421         ghostPanel.setSize(box.width, box.height);
1422         me.el.hide();
1423         if (me.floatingItems) {
1424             me.floatingItems.hide();
1425         }
1426         return ghostPanel;
1427     },
1428
1429     // private
1430     unghost: function(show, matchPosition) {
1431         var me = this;
1432         if (!me.ghostPanel) {
1433             return;
1434         }
1435         if (show !== false) {
1436             me.el.show();
1437             if (matchPosition !== false) {
1438                 me.setPosition(me.ghostPanel.getPosition());
1439             }
1440             if (me.floatingItems) {
1441                 me.floatingItems.show();
1442             }
1443             Ext.defer(me.focus, 10, me);
1444         }
1445         me.ghostPanel.el.hide();
1446     },
1447
1448     initResizable: function(resizable) {
1449         if (this.collapsed) {
1450             resizable.disabled = true;
1451         }
1452         this.callParent([resizable]);
1453     }
1454 });
1455 </pre>
1456 </body>
1457 </html>