X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/c930e9176a5a85509c5b0230e2bff5c22a591432..6e39d509471fe9b4e2660e0d1631b350d0c66f40:/src/widgets/Panel.js diff --git a/src/widgets/Panel.js b/src/widgets/Panel.js index dbb38405..13e08995 100644 --- a/src/widgets/Panel.js +++ b/src/widgets/Panel.js @@ -1,5 +1,5 @@ /*! - * Ext JS Library 3.0.0 + * Ext JS Library 3.1.0 * Copyright(c) 2006-2009 Ext JS, LLC * licensing@extjs.com * http://www.extjs.com/license @@ -13,7 +13,7 @@ * of being configured with a {@link Ext.Container#layout layout}, and containing child Components.

*

When either specifying child {@link Ext.Component#items items} of a Panel, or dynamically {@link Ext.Container#add adding} Components * to a Panel, remember to consider how you wish the Panel to arrange those child elements, and whether - * those child elements need to be sized using one of Ext's built-in {@link Ext.Container#layout layout} schemes. By + * those child elements need to be sized using one of Ext's built-in {@link Ext.Container#layout layout} schemes. By * default, Panels use the {@link Ext.layout.ContainerLayout ContainerLayout} scheme. This simply renders * child components, appending them one after the other inside the Container, and does not apply any sizing * at all.

@@ -32,7 +32,7 @@ Ext.Panel = Ext.extend(Ext.Container, { /** * The Panel's header {@link Ext.Element Element}. Read-only. *

This Element is used to house the {@link #title} and {@link #tools}

- *

Note: see the Note for {@link Ext.Component#el el} also.

+ *

Note: see the Note for {@link Ext.Component#el el} also.

* @type Ext.Element * @property header */ @@ -45,7 +45,7 @@ Ext.Panel = Ext.extend(Ext.Container, { *

If this Panel is intended to be used as the host of a Layout (See {@link #layout} * then the body Element must not be loaded or changed - it is under the control * of the Panel's Layout. - *

Note: see the Note for {@link Ext.Component#el el} also.

+ *

Note: see the Note for {@link Ext.Component#el el} also.

* @type Ext.Element * @property body */ @@ -65,8 +65,8 @@ Ext.Panel = Ext.extend(Ext.Container, { *

A {@link Ext.DomHelper DomHelper} element specification object may be specified for any * Panel Element.

*

By default, the Default element in the table below will be used for the html markup to - * create a child element with the commensurate Default class name (baseCls will be - * replaced by {@link #baseCls}):

+ * create a child element with the commensurate Default class name (baseCls will be + * replaced by {@link #baseCls}):

*
      * Panel      Default  Default             Custom      Additional       Additional
      * Element    element  class               element     class            style
@@ -102,51 +102,51 @@ new Ext.Panel({
     footerStyle:    'background-color:red' // see {@link #bodyStyle}
 });
      * 
- *

The example above also explicitly creates a {@link #footer} with custom markup and + *

The example above also explicitly creates a {@link #footer} with custom markup and * styling applied.

*/ /** * @cfg {Object} headerCfg *

A {@link Ext.DomHelper DomHelper} element specification object specifying the element structure - * of this Panel's {@link #header} Element. See {@link #bodyCfg} also.

+ * of this Panel's {@link #header} Element. See {@link #bodyCfg} also.

*/ /** * @cfg {Object} bwrapCfg *

A {@link Ext.DomHelper DomHelper} element specification object specifying the element structure - * of this Panel's {@link #bwrap} Element. See {@link #bodyCfg} also.

+ * of this Panel's {@link #bwrap} Element. See {@link #bodyCfg} also.

*/ /** * @cfg {Object} tbarCfg *

A {@link Ext.DomHelper DomHelper} element specification object specifying the element structure - * of this Panel's {@link #tbar} Element. See {@link #bodyCfg} also.

+ * of this Panel's {@link #tbar} Element. See {@link #bodyCfg} also.

*/ /** * @cfg {Object} bbarCfg *

A {@link Ext.DomHelper DomHelper} element specification object specifying the element structure - * of this Panel's {@link #bbar} Element. See {@link #bodyCfg} also.

+ * of this Panel's {@link #bbar} Element. See {@link #bodyCfg} also.

*/ /** * @cfg {Object} footerCfg *

A {@link Ext.DomHelper DomHelper} element specification object specifying the element structure - * of this Panel's {@link #footer} Element. See {@link #bodyCfg} also.

+ * of this Panel's {@link #footer} Element. See {@link #bodyCfg} also.

*/ /** * @cfg {Boolean} closable * Panels themselves do not directly support being closed, but some Panel subclasses do (like - * {@link Ext.Window}) or a Panel Class within an {@link Ext.TabPanel}. Specify true - * to enable closing in such situations. Defaults to false. + * {@link Ext.Window}) or a Panel Class within an {@link Ext.TabPanel}. Specify true + * to enable closing in such situations. Defaults to false. */ /** * The Panel's footer {@link Ext.Element Element}. Read-only. - *

This Element is used to house the Panel's {@link #buttons} or {@link #fbar}.

- *

Note: see the Note for {@link Ext.Component#el el} also.

+ *

This Element is used to house the Panel's {@link #buttons} or {@link #fbar}.

+ *

Note: see the Note for {@link Ext.Component#el el} also.

* @type Ext.Element * @property footer */ /** * @cfg {Mixed} applyTo *

The id of the node, a DOM node or an existing Element corresponding to a DIV that is already present in - * the document that specifies some panel-specific structural markup. When applyTo is used, + * the document that specifies some panel-specific structural markup. When applyTo is used, * constituent parts of the panel can be specified by CSS class name within the main element, and the panel * will automatically create those components from that markup. Any required components not specified in the * markup will be autogenerated if necessary.

@@ -177,7 +177,7 @@ new Ext.Panel({ *

The bottom toolbar of the panel. This can be a {@link Ext.Toolbar} object, a toolbar config, or an array of * buttons/button configs to be added to the toolbar. Note that this is not available as a property after render. * To access the bottom toolbar after render, use {@link #getBottomToolbar}.

- *

Note: Although a Toolbar may contain Field components, these will not be updated by a load + *

Note: Although a Toolbar may contain Field components, these will not be updated by a load * of an ancestor FormPanel. A Panel's toolbars are not part of the standard Container->Component hierarchy, and * so are not scanned to collect form items. However, the values will be submitted because form * submission parameters are collected from the DOM tree.

@@ -186,8 +186,8 @@ new Ext.Panel({ *

A {@link Ext.Toolbar Toolbar} object, a Toolbar config, or an array of * {@link Ext.Button Button}s/{@link Ext.Button Button} configs, describing a {@link Ext.Toolbar Toolbar} to be rendered into this Panel's footer element.

*

After render, the fbar property will be an {@link Ext.Toolbar Toolbar} instance.

- *

If {@link #buttons} are specified, they will supersede the fbar configuration property.

- * The Panel's {@link #buttonAlign} configuration affects the layout of these items, for example: + *

If {@link #buttons} are specified, they will supersede the fbar configuration property.

+ * The Panel's {@link #buttonAlign} configuration affects the layout of these items, for example: *

 var w = new Ext.Window({
     height: 250,
@@ -199,7 +199,7 @@ var w = new Ext.Window({
             text: 'bbar Right'
         }]
     }),
-    {@link #buttonAlign}: 'left', // anything but 'center' or 'right' and you can use "-", and "->"
+    {@link #buttonAlign}: 'left', // anything but 'center' or 'right' and you can use '-', and '->'
                                   // to control the alignment of fbar items
     fbar: [{
         text: 'fbar Left'
@@ -208,40 +208,40 @@ var w = new Ext.Window({
     }]
 }).show();
      * 
- *

Note: Although a Toolbar may contain Field components, these will not be updated by a load + *

Note: Although a Toolbar may contain Field components, these will not be updated by a load * of an ancestor FormPanel. A Panel's toolbars are not part of the standard Container->Component hierarchy, and * so are not scanned to collect form items. However, the values will be submitted because form * submission parameters are collected from the DOM tree.

*/ /** * @cfg {Boolean} header - * true to create the Panel's header element explicitly, false to skip creating - * it. If a {@link #title} is set the header will be created automatically, otherwise it will not. - * If a {@link #title} is set but header is explicitly set to false, the header + * true to create the Panel's header element explicitly, false to skip creating + * it. If a {@link #title} is set the header will be created automatically, otherwise it will not. + * If a {@link #title} is set but header is explicitly set to false, the header * will not be rendered. */ /** * @cfg {Boolean} footer - * true to create the footer element explicitly, false to skip creating it. The footer - * will be created automatically if {@link #buttons} or a {@link #fbar} have - * been configured. See {@link #bodyCfg} for an example. + * true to create the footer element explicitly, false to skip creating it. The footer + * will be created automatically if {@link #buttons} or a {@link #fbar} have + * been configured. See {@link #bodyCfg} for an example. */ /** * @cfg {String} title * The title text to be used as innerHTML (html tags are accepted) to display in the panel - * {@link #header} (defaults to ''). When a title is specified the - * {@link #header} element will automatically be created and displayed unless - * {@link #header} is explicitly set to false. If you do not want to specify a - * title at config time, but you may want one later, you must either specify a non-empty - * title (a blank space ' ' will do) or header:true so that the container + * {@link #header} (defaults to ''). When a title is specified the + * {@link #header} element will automatically be created and displayed unless + * {@link #header} is explicitly set to false. If you do not want to specify a + * title at config time, but you may want one later, you must either specify a non-empty + * title (a blank space ' ' will do) or header:true so that the container * element will get created. */ /** * @cfg {Array} buttons - * buttons will be used as {@link Ext.Container#items items} for the toolbar in - * the footer ({@link #fbar}). Typically the value of this configuration property will be + * buttons will be used as {@link Ext.Container#items items} for the toolbar in + * the footer ({@link #fbar}). Typically the value of this configuration property will be * an array of {@link Ext.Button}s or {@link Ext.Button} configuration objects. - * If an item is configured with minWidth or the Panel is configured with minButtonWidth, + * If an item is configured with minWidth or the Panel is configured with minButtonWidth, * that width will be applied to the item. */ /** @@ -254,7 +254,7 @@ var w = new Ext.Window({ */ /** * @cfg {Boolean} frame - * false by default to render with plain 1px square borders. true to render with + * false by default to render with plain 1px square borders. true to render with * 9 elements, complete with custom rounded corners (also see {@link Ext.Element#boxWrap}). *

The template generated for each condition is depicted below:


      *
@@ -326,40 +326,40 @@ var w = new Ext.Window({
     /**
      * @cfg {Array} tools
      * An array of tool button configs to be added to the header tool area. When rendered, each tool is
-     * stored as an {@link Ext.Element Element} referenced by a public property called tools.<tool-type>
+     * stored as an {@link Ext.Element Element} referenced by a public property called tools.<tool-type>
      * 

Each tool config may contain the following properties: *

    *
  • id : String
    Required. The type - * of tool to create. By default, this assigns a CSS class of the form x-tool-<tool-type> to the + * of tool to create. By default, this assigns a CSS class of the form x-tool-<tool-type> to the * resulting tool Element. Ext provides CSS rules, and an icon sprite containing images for the tool types listed below. * The developer may implement custom tools by supplying alternate CSS rules and background images: *
      - *
      toggle (Created by default when {@link #collapsible} is true)
      - *
      close
      - *
      minimize
      - *
      maximize
      - *
      restore
      - *
      gear
      - *
      pin
      - *
      unpin
      - *
      right
      - *
      left
      - *
      up
      - *
      down
      - *
      refresh
      - *
      minus
      - *
      plus
      - *
      help
      - *
      search
      - *
      save
      - *
      print
      + *
      toggle (Created by default when {@link #collapsible} is true)
      + *
      close
      + *
      minimize
      + *
      maximize
      + *
      restore
      + *
      gear
      + *
      pin
      + *
      unpin
      + *
      right
      + *
      left
      + *
      up
      + *
      down
      + *
      refresh
      + *
      minus
      + *
      plus
      + *
      help
      + *
      search
      + *
      save
      + *
      print
      *
  • *
  • handler : Function
    Required. The function to * call when clicked. Arguments passed are:
      *
    • event : Ext.EventObject
      The click event.
    • *
    • toolEl : Ext.Element
      The tool Element.
    • *
    • panel : Ext.Panel
      The host Panel
    • - *
    • tc : Ext.Panel
      The tool configuration object
    • + *
    • tc : Object
      The tool configuration object
    • *
  • *
  • stopEvent : Boolean
    Defaults to true. Specify as false to allow click event to propagate.
  • *
  • scope : Object
    The scope in which to call the handler.
  • @@ -390,7 +390,7 @@ tools:[{ } }]
- *

For the custom id of 'help' define two relevant css classes with a link to + *

For the custom id of 'help' define two relevant css classes with a link to * a 15x15 image:

*

 .x-tool-help {background-image: url(images/help.png);}
@@ -425,7 +425,7 @@ var win = new Ext.Window({
     height:300,
     closeAction:'hide'
 });
- *

Note that the CSS class "x-tool-pdf" should have an associated style rule which provides an + *

Note that the CSS class 'x-tool-pdf' should have an associated style rule which provides an * appropriate background image, something like:


     a.x-tool-pdf {background-image: url(../shared/extjs/images/pdf.gif)!important;}
@@ -433,96 +433,63 @@ var win = new Ext.Window({
      */
     /**
      * @cfg {Boolean} hideCollapseTool
-     * true to hide the expand/collapse toggle button when {@link #collapsible} == true,
-     * false to display it (defaults to false).
+     * true to hide the expand/collapse toggle button when {@link #collapsible} == true,
+     * false to display it (defaults to false).
      */
     /**
      * @cfg {Boolean} titleCollapse
-     * true to allow expanding and collapsing the panel (when {@link #collapsible} = true)
-     * by clicking anywhere in the header bar, false) to allow it only by clicking to tool button
-     * (defaults to false)). If this panel is a child item of a border layout also see the
+     * true to allow expanding and collapsing the panel (when {@link #collapsible} = true)
+     * by clicking anywhere in the header bar, false) to allow it only by clicking to tool button
+     * (defaults to false)). If this panel is a child item of a border layout also see the
      * {@link Ext.layout.BorderLayout.Region BorderLayout.Region}
-     * {@link Ext.layout.BorderLayout.Region#floatable floatable} config option.
-     */
-    /**
-     * @cfg {Boolean} autoScroll
-     * true to use overflow:'auto' on the panel's body element and show scroll bars automatically when
-     * necessary, false to clip any overflowing content (defaults to false).
+     * {@link Ext.layout.BorderLayout.Region#floatable floatable} config option.
      */
+
     /**
      * @cfg {Mixed} floating
      * 

This property is used to configure the underlying {@link Ext.Layer}. Acceptable values for this * configuration property are:

    - *
  • false : Default.
    Display the panel inline where it is + *
  • false : Default.
    Display the panel inline where it is * rendered.
  • - *
  • true :
    Float the panel (absolute position it with automatic + *
  • true :
    Float the panel (absolute position it with automatic * shimming and shadow).
      *
      Setting floating to true will create an Ext.Layer for this panel and display the * panel at negative offsets so that it is hidden.
      *
      Since the panel will be absolute positioned, the position must be set explicitly - * after render (e.g., myPanel.setPosition(100,100);).
      + * after render (e.g., myPanel.setPosition(100,100);).
    *
    Note: when floating a panel you should always assign a fixed width, * otherwise it will be auto width and will expand to fill to the right edge of the viewport.
    *
- *
  • {@link Ext.Layer object} :
    The specified object will be used + *
  • {@link Ext.Layer object} :
    The specified object will be used * as the configuration object for the {@link Ext.Layer} that will be created.
  • * */ /** * @cfg {Boolean/String} shadow - * true (or a valid Ext.Shadow {@link Ext.Shadow#mode} value) to display a shadow behind the - * panel, false to display no shadow (defaults to 'sides'). Note that this option - * only applies when {@link #floating} = true. + * true (or a valid Ext.Shadow {@link Ext.Shadow#mode} value) to display a shadow behind the + * panel, false to display no shadow (defaults to 'sides'). Note that this option + * only applies when {@link #floating} = true. */ /** * @cfg {Number} shadowOffset - * The number of pixels to offset the shadow if displayed (defaults to 4). Note that this - * option only applies when {@link #floating} = true. + * The number of pixels to offset the shadow if displayed (defaults to 4). Note that this + * option only applies when {@link #floating} = true. */ /** * @cfg {Boolean} shim - * false to disable the iframe shim in browsers which need one (defaults to true). - * Note that this option only applies when {@link #floating} = true. - */ - /** - * @cfg {String/Object} html - * An HTML fragment, or a {@link Ext.DomHelper DomHelper} specification to use as the panel's body - * content (defaults to ''). The HTML content is added by the Panel's {@link #afterRender} method, - * and so the document will not contain this HTML at the time the {@link #render} event is fired. - * This content is inserted into the body before any configured {@link #contentEl} is appended. - */ - /** - * @cfg {String} contentEl - *

    Specify the id of an existing HTML node to use as the panel's body content - * (defaults to '').

      - *
    • Description :
        - *
        This config option is used to take an existing HTML element and place it in the body - * of a new panel (it simply moves the specified DOM element into the body element of the Panel - * when the Panel is rendered to use as the content (it is not going to be the - * actual panel itself).
        - *
    • - *
    • Notes :
        - *
        The specified HTML Element is appended to the Panel's {@link #body} Element by the - * Panel's {@link #afterRender} method after any configured {@link #html HTML} has - * been inserted, and so the document will not contain this HTML at the time the - * {@link #render} event is fired.
        - *
        The specified HTML element used will not participate in any layout scheme that the - * Panel may use. It's just HTML. Layouts operate on child items.
        - *
        Add either the x-hidden or the x-hide-display CSS class to - * prevent a brief flicker of the content before it is rendered to the panel.
        - *
    • - *
    + * false to disable the iframe shim in browsers which need one (defaults to true). + * Note that this option only applies when {@link #floating} = true. */ /** * @cfg {Object/Array} keys * A {@link Ext.KeyMap} config object (in the format expected by {@link Ext.KeyMap#addBinding} - * used to assign custom key handling to this panel (defaults to null). + * used to assign custom key handling to this panel (defaults to null). */ /** * @cfg {Boolean/Object} draggable - *

    true to enable dragging of this Panel (defaults to false).

    + *

    true to enable dragging of this Panel (defaults to false).

    *

    For custom drag/drop implementations, an Ext.Panel.DD config could also be passed - * in this config instead of true. Ext.Panel.DD is an internal, undocumented class which + * in this config instead of true. Ext.Panel.DD is an internal, undocumented class which * moves a proxy Element around in place of the Panel's element, but provides no other behaviour * during dragging or on drop. It is a subclass of {@link Ext.dd.DragSource}, so behaviour may be * added by implementing the interface methods of {@link Ext.dd.DragDrop} e.g.: @@ -564,15 +531,9 @@ new Ext.Panel({ }).show();

    */ - /** - * @cfg {String} tabTip - * A string to be used as innerHTML (html tags are accepted) to show in a tooltip when mousing over - * the tab of a Ext.Panel which is an item of a {@link Ext.TabPanel}. {@link Ext.QuickTips}.init() - * must be called in order for the tips to render. - */ /** * @cfg {Boolean} disabled - * Render this panel disabled (default is false). An important note when using the disabled + * Render this panel disabled (default is false). An important note when using the disabled * config on panels is that IE will often fail to initialize the disabled mask element correectly if * the panel's layout has not yet completed by the time the Panel is disabled during the render process. * If you experience this issue, you may need to instead use the {@link #afterlayout} event to initialize @@ -593,10 +554,10 @@ new Ext.Panel({ */ /** * @cfg {Boolean} autoHeight - * true to use height:'auto', false to use fixed height (defaults to false). - * Note: Setting autoHeight:true means that the browser will manage the panel's height + * true to use height:'auto', false to use fixed height (defaults to false). + * Note: Setting autoHeight: true means that the browser will manage the panel's height * based on its contents, and that Ext will not manage it at all. If the panel is within a layout that - * manages dimensions (fit, border, etc.) then setting autoHeight:true + * manages dimensions (fit, border, etc.) then setting autoHeight: true * can cause issues with scrolling and will not generally work as expected since the panel will take * on the height of its contents rather than the height required by the Ext layout. */ @@ -604,64 +565,64 @@ new Ext.Panel({ /** * @cfg {String} baseCls - * The base CSS class to apply to this panel's element (defaults to 'x-panel'). - *

    Another option available by default is to specify 'x-plain' which strips all styling + * The base CSS class to apply to this panel's element (defaults to 'x-panel'). + *

    Another option available by default is to specify 'x-plain' which strips all styling * except for required attributes for Ext layouts to function (e.g. overflow:hidden). - * See {@link #unstyled} also.

    + * See {@link #unstyled} also.

    */ baseCls : 'x-panel', /** * @cfg {String} collapsedCls * A CSS class to add to the panel's element after it has been collapsed (defaults to - * 'x-panel-collapsed'). + * 'x-panel-collapsed'). */ collapsedCls : 'x-panel-collapsed', /** * @cfg {Boolean} maskDisabled - * true to mask the panel when it is {@link #disabled}, false to not mask it (defaults - * to true). Either way, the panel will always tell its contained elements to disable themselves + * true to mask the panel when it is {@link #disabled}, false to not mask it (defaults + * to true). Either way, the panel will always tell its contained elements to disable themselves * when it is disabled, but masking the panel can provide an additional visual cue that the panel is * disabled. */ maskDisabled : true, /** * @cfg {Boolean} animCollapse - * true to animate the transition when the panel is collapsed, false to skip the - * animation (defaults to true if the {@link Ext.Fx} class is available, otherwise false). + * true to animate the transition when the panel is collapsed, false to skip the + * animation (defaults to true if the {@link Ext.Fx} class is available, otherwise false). */ animCollapse : Ext.enableFx, /** * @cfg {Boolean} headerAsText - * true to display the panel {@link #title} in the {@link #header}, - * false to hide it (defaults to true). + * true to display the panel {@link #title} in the {@link #header}, + * false to hide it (defaults to true). */ headerAsText : true, /** * @cfg {String} buttonAlign - * The alignment of any {@link #buttons} added to this panel. Valid values are 'right', - * 'left' and 'center' (defaults to 'right'). + * The alignment of any {@link #buttons} added to this panel. Valid values are 'right', + * 'left' and 'center' (defaults to 'right'). */ buttonAlign : 'right', /** * @cfg {Boolean} collapsed - * true to render the panel collapsed, false to render it expanded (defaults to - * false). + * true to render the panel collapsed, false to render it expanded (defaults to + * false). */ collapsed : false, /** * @cfg {Boolean} collapseFirst - * true to make sure the collapse/expand toggle button always renders first (to the left of) - * any other tools in the panel's title bar, false to render it last (defaults to true). + * true to make sure the collapse/expand toggle button always renders first (to the left of) + * any other tools in the panel's title bar, false to render it last (defaults to true). */ collapseFirst : true, /** * @cfg {Number} minButtonWidth - * Minimum width in pixels of all {@link #buttons} in this panel (defaults to 75) + * Minimum width in pixels of all {@link #buttons} in this panel (defaults to 75) */ minButtonWidth : 75, /** * @cfg {Boolean} unstyled - * Overrides the {@link #baseCls} setting to {@link #baseCls} = 'x-plain' which renders + * Overrides the {@link #baseCls} setting to {@link #baseCls} = 'x-plain' which renders * the panel unstyled except for required attributes for Ext layouts to function (e.g. overflow:hidden). */ /** @@ -671,24 +632,38 @@ new Ext.Panel({ * make sure a structural element is rendered even if not specified at config time (for example, you may want * to add a button or toolbar dynamically after the panel has been rendered). Adding those elements to this * list will allocate the required placeholders in the panel when it is rendered. Valid values are
      - *
    • header
    • - *
    • tbar (top bar)
    • - *
    • body
    • - *
    • bbar (bottom bar)
    • - *
    • footer
    • + *
    • header
    • + *
    • tbar (top bar)
    • + *
    • body
    • + *
    • bbar (bottom bar)
    • + *
    • footer
    • *
    - * Defaults to 'body'. + * Defaults to 'body'. */ elements : 'body', /** * @cfg {Boolean} preventBodyReset - * Defaults to false. When set to true, an extra css class 'x-panel-normal' + * Defaults to false. When set to true, an extra css class 'x-panel-normal' * will be added to the panel's element, effectively applying css styles suggested by the W3C * (see http://www.w3.org/TR/CSS21/sample.html) to the Panel's body element (not the header, * footer, etc.). */ preventBodyReset : false, + /** + * @cfg {Number/String} padding + * A shortcut for setting a padding style on the body element. The value can either be + * a number to be applied to all sides, or a normal css string describing padding. + * Defaults to undefined. + * + */ + padding: undefined, + + /** @cfg {String} resizeEvent + * The event to listen to for resizing in layouts. Defaults to 'bodyresize'. + */ + resizeEvent: 'bodyresize', + // protected - these could be used to customize the behavior of the window, // but changing them would not be useful without further mofifications and // could lead to unexpected or undesirable results. @@ -802,19 +777,18 @@ new Ext.Panel({ this.baseCls = 'x-plain'; } + + this.toolbars = []; // shortcuts if(this.tbar){ this.elements += ',tbar'; - if(Ext.isObject(this.tbar)){ - this.topToolbar = this.tbar; - } + this.topToolbar = this.createToolbar(this.tbar); delete this.tbar; + } if(this.bbar){ this.elements += ',bbar'; - if(Ext.isObject(this.bbar)){ - this.bottomToolbar = this.bbar; - } + this.bottomToolbar = this.createToolbar(this.bbar); delete this.bbar; } @@ -831,33 +805,61 @@ new Ext.Panel({ } if(this.buttons){ - this.elements += ',footer'; - var btns = this.buttons; - /** - * This Panel's Array of buttons as created from the {@link #buttons} - * config property. Read only. - * @type Array - * @property buttons - */ - this.buttons = []; - for(var i = 0, len = btns.length; i < len; i++) { - if(btns[i].render){ // button instance - this.buttons.push(btns[i]); - }else if(btns[i].xtype){ - this.buttons.push(Ext.create(btns[i], 'button')); - }else{ - this.addButton(btns[i]); - } - } + this.fbar = this.buttons; + delete this.buttons; } if(this.fbar){ - this.elements += ',footer'; + this.createFbar(this.fbar); } if(this.autoLoad){ this.on('render', this.doAutoLoad, this, {delay:10}); } }, + // private + createFbar : function(fbar){ + var min = this.minButtonWidth; + this.elements += ',footer'; + this.fbar = this.createToolbar(fbar, { + buttonAlign: this.buttonAlign, + toolbarCls: 'x-panel-fbar', + enableOverflow: false, + defaults: function(c){ + return { + minWidth: c.minWidth || min + }; + } + }); + //@compat addButton and buttons could possibly be removed + //@target 4.0 + /** + * This Panel's Array of buttons as created from the {@link #buttons} + * config property. Read only. + * @type Array + * @property buttons + */ + this.fbar.items.each(function(c){ + c.minWidth = c.minWidth || this.minButtonWidth; + }, this); + this.buttons = this.fbar.items.items; + }, + + // private + createToolbar: function(tb, options){ + var result; + // Convert array to proper toolbar config + if(Ext.isArray(tb)){ + tb = { + items: tb + }; + } + result = tb.events ? Ext.apply(tb, options) : this.createComponent(Ext.apply({}, tb, options), 'toolbar'); + result.ownerCt = this; + result.bufferResize = false; + this.toolbars.push(result); + return result; + }, + // private createElement : function(name, pnode){ if(this[name]){ @@ -889,7 +891,25 @@ new Ext.Panel({ var el = this.el, d = el.dom, - bw; + bw, + ts; + + + if(this.collapsible && !this.hideCollapseTool){ + this.tools = this.tools ? this.tools.slice(0) : []; + this.tools[this.collapseFirst?'unshift':'push']({ + id: 'toggle', + handler : this.toggleCollapse, + scope: this + }); + } + + if(this.tools){ + ts = this.tools; + this.elements += (this.header !== false) ? ',header' : ''; + } + this.tools = {}; + el.addClass(this.baseCls); if(d.firstChild){ // existing markup this.header = el.down('.'+this.headerCls); @@ -936,6 +956,13 @@ new Ext.Panel({ if(!this.footer){ this.bwrap.dom.lastChild.className += ' x-panel-nofooter'; } + /* + * Store a reference to this element so: + * a) We aren't looking it up all the time + * b) The last element is reported incorrectly when using a loadmask + */ + this.ft = Ext.get(this.bwrap.dom.lastChild); + this.mc = Ext.get(mc); }else{ this.createElement('header', d); this.createElement('bwrap', d); @@ -955,7 +982,7 @@ new Ext.Panel({ } } - if(this.padding !== undefined) { + if(Ext.isDefined(this.padding)){ this.body.setStyle('padding', this.body.addUnits(this.padding)); } @@ -1000,79 +1027,26 @@ new Ext.Panel({ this.makeFloating(this.floating); } - if(this.collapsible){ - this.tools = this.tools ? this.tools.slice(0) : []; - if(!this.hideCollapseTool){ - this.tools[this.collapseFirst?'unshift':'push']({ - id: 'toggle', - handler : this.toggleCollapse, - scope: this - }); - } - if(this.titleCollapse && this.header){ - this.mon(this.header, 'click', this.toggleCollapse, this); - this.header.setStyle('cursor', 'pointer'); - } + if(this.collapsible && this.titleCollapse && this.header){ + this.mon(this.header, 'click', this.toggleCollapse, this); + this.header.setStyle('cursor', 'pointer'); } - if(this.tools){ - var ts = this.tools; - this.tools = {}; + if(ts){ this.addTool.apply(this, ts); - }else{ - this.tools = {}; } - - if(this.buttons && this.buttons.length > 0){ - this.fbar = new Ext.Toolbar({ - items: this.buttons, - toolbarCls: 'x-panel-fbar' - }); - } - this.toolbars = []; if(this.fbar){ - this.fbar = Ext.create(this.fbar, 'toolbar'); - this.fbar.enableOverflow = false; - if(this.fbar.items){ - this.fbar.items.each(function(c){ - c.minWidth = c.minWidth || this.minButtonWidth; - }, this); - } - this.fbar.toolbarCls = 'x-panel-fbar'; - - var bct = this.footer.createChild({cls: 'x-panel-btns x-panel-btns-'+this.buttonAlign}); - this.fbar.ownerCt = this; - this.fbar.render(bct); - bct.createChild({cls:'x-clear'}); - this.toolbars.push(this.fbar); + this.footer.addClass('x-panel-btns'); + this.fbar.render(this.footer); + this.footer.createChild({cls:'x-clear'}); } if(this.tbar && this.topToolbar){ - if(Ext.isArray(this.topToolbar)){ - this.topToolbar = new Ext.Toolbar(this.topToolbar); - }else if(!this.topToolbar.events){ - this.topToolbar = Ext.create(this.topToolbar, 'toolbar'); - } - this.topToolbar.ownerCt = this; this.topToolbar.render(this.tbar); - this.toolbars.push(this.topToolbar); } if(this.bbar && this.bottomToolbar){ - if(Ext.isArray(this.bottomToolbar)){ - this.bottomToolbar = new Ext.Toolbar(this.bottomToolbar); - }else if(!this.bottomToolbar.events){ - this.bottomToolbar = Ext.create(this.bottomToolbar, 'toolbar'); - } - this.bottomToolbar.ownerCt = this; this.bottomToolbar.render(this.bbar); - this.toolbars.push(this.bottomToolbar); + } - Ext.each(this.toolbars, function(tb){ - tb.on({ - scope: this, - afterlayout: this.syncHeight, - remove: this.syncHeight - }); - }, this); }, /** @@ -1088,12 +1062,12 @@ new Ext.Panel({ this.header.addClass('x-panel-icon'); this.header.replaceClass(old, this.iconCls); }else{ - var hd = this.header.dom; - var img = hd.firstChild && String(hd.firstChild.tagName).toLowerCase() == 'img' ? hd.firstChild : null; + var hd = this.header, + img = hd.child('img.x-panel-inline-icon'); if(img){ Ext.fly(img).replaceClass(old, this.iconCls); }else{ - Ext.DomHelper.insertBefore(hd.firstChild, { + Ext.DomHelper.insertBefore(hd.dom.firstChild, { tag:'img', src: Ext.BLANK_IMAGE_URL, cls:'x-panel-inline-icon '+this.iconCls }); } @@ -1105,18 +1079,16 @@ new Ext.Panel({ // private makeFloating : function(cfg){ this.floating = true; - this.el = new Ext.Layer( - Ext.isObject(cfg) ? cfg : { - shadow: this.shadow !== undefined ? this.shadow : 'sides', - shadowOffset: this.shadowOffset, - constrain:false, - shim: this.shim === false ? false : undefined - }, this.el - ); + this.el = new Ext.Layer(Ext.apply({}, cfg, { + shadow: Ext.isDefined(this.shadow) ? this.shadow : 'sides', + shadowOffset: this.shadowOffset, + constrain:false, + shim: this.shim === false ? false : undefined + }), this.el); }, /** - * Returns the {@link Ext.Toolbar toolbar} from the top ({@link #tbar}) section of the panel. + * Returns the {@link Ext.Toolbar toolbar} from the top ({@link #tbar}) section of the panel. * @return {Ext.Toolbar} The toolbar */ getTopToolbar : function(){ @@ -1124,7 +1096,7 @@ new Ext.Panel({ }, /** - * Returns the {@link Ext.Toolbar toolbar} from the bottom ({@link #bbar}) section of the panel. + * Returns the {@link Ext.Toolbar toolbar} from the bottom ({@link #bbar}) section of the panel. * @return {Ext.Toolbar} The toolbar */ getBottomToolbar : function(){ @@ -1137,32 +1109,38 @@ new Ext.Panel({ * @param {String/Object} config A valid {@link Ext.Button} config. A string will become the text for a default * button config, an object will be treated as a button config object. * @param {Function} handler The function to be called on button {@link Ext.Button#click} - * @param {Object} scope The scope to use for the button handler function + * @param {Object} scope The scope (this reference) in which the button handler function is executed. Defaults to the Button. * @return {Ext.Button} The button that was added */ addButton : function(config, handler, scope){ - var bc = { - handler: handler, - scope: scope, - minWidth: this.minButtonWidth, - hideParent:true - }; - if(typeof config == "string"){ - bc.text = config; - }else{ - Ext.apply(bc, config); + if(!this.fbar){ + this.createFbar([]); } - var btn = new Ext.Button(bc); - if(!this.buttons){ - this.buttons = []; + if(handler){ + if(Ext.isString(config)){ + config = {text: config}; + } + config = Ext.apply({ + handler: handler, + scope: scope + }, config) } - this.buttons.push(btn); - return btn; + return this.fbar.add(config); }, // private addTool : function(){ - if(!this[this.toolTarget]) { // no where to render tools! + if(!this.rendered){ + if(!this.tools){ + this.tools = []; + } + Ext.each(arguments, function(arg){ + this.tools.push(arg) + }, this); + return; + } + // nowhere to render tools! + if(!this[this.toolTarget]){ return; } if(!this.toolTemplate){ @@ -1202,35 +1180,32 @@ new Ext.Panel({ } }, - onLayout : function(){ - if(this.toolbars.length > 0){ - this.duringLayout = true; + onLayout : function(shallow, force){ + if(this.hasLayout && this.toolbars.length > 0){ Ext.each(this.toolbars, function(tb){ - tb.doLayout(); + tb.doLayout(undefined, force); }); - delete this.duringLayout; this.syncHeight(); } }, syncHeight : function(){ - if(!(this.autoHeight || this.duringLayout)){ - var last = this.lastSize; - if(last && !Ext.isEmpty(last.height)){ - var old = last.height, h = this.el.getHeight(); - if(old != 'auto' && old != h){ - var bd = this.body, bdh = bd.getHeight(); - h = Math.max(bdh + old - h, 0); - if(bdh > 0 && bdh != h){ - bd.setHeight(h); - if(Ext.isIE && h <= 0){ - return; - } - var sz = bd.getSize(); - this.fireEvent('bodyresize', sz.width, sz.height); - } - } - } + var h = this.toolbarHeight, + bd = this.body, + lsh = this.lastSize.height, + sz; + + if(this.autoHeight || !Ext.isDefined(lsh) || lsh == 'auto'){ + return; + } + + + if(h != this.getToolbarHeight()){ + h = Math.max(0, this.adjustBodyHeight(lsh - this.getFrameHeight())); + bd.setHeight(h); + sz = bd.getSize(); + this.toolbarHeight = this.getToolbarHeight(); + this.onBodyResize(sz.width, sz.height); } }, @@ -1263,7 +1238,7 @@ new Ext.Panel({ }; }, - // private + // private afterRender : function(){ if(this.floating && !this.hidden){ this.el.show(); @@ -1271,35 +1246,13 @@ new Ext.Panel({ if(this.title){ this.setTitle(this.title); } - this.setAutoScroll(); - if(this.html){ - this.body.update(Ext.isObject(this.html) ? - Ext.DomHelper.markup(this.html) : - this.html); - delete this.html; - } - if(this.contentEl){ - var ce = Ext.getDom(this.contentEl); - Ext.fly(ce).removeClass(['x-hidden', 'x-hide-display']); - this.body.dom.appendChild(ce); - } if(this.collapsed){ this.collapsed = false; this.collapse(false); } Ext.Panel.superclass.afterRender.call(this); // do sizing calcs last this.initEvents(); - }, - - // private - setAutoScroll : function(){ - if(this.rendered && this.autoScroll){ - var el = this.body || this.el; - if(el){ - el.setOverflow('auto'); - } - } - }, + }, // private getKeyMap : function(){ @@ -1317,6 +1270,20 @@ new Ext.Panel({ if(this.draggable){ this.initDraggable(); } + if(this.toolbars.length > 0){ + Ext.each(this.toolbars, function(tb){ + tb.doLayout(); + tb.on({ + scope: this, + afterlayout: this.syncHeight, + remove: this.syncHeight + }); + }, this); + if(!this.ownerCt){ + this.syncHeight(); + } + } + }, // private @@ -1329,21 +1296,25 @@ new Ext.Panel({ * @type Ext.dd.DragSource. * @property dd */ - this.dd = new Ext.Panel.DD(this, typeof this.draggable == 'boolean' ? null : this.draggable); + this.dd = new Ext.Panel.DD(this, Ext.isBoolean(this.draggable) ? null : this.draggable); }, // private - beforeEffect : function(){ + beforeEffect : function(anim){ if(this.floating){ this.el.beforeAction(); } - this.el.addClass('x-panel-animated'); + if(anim !== false){ + this.el.addClass('x-panel-animated'); + } }, // private - afterEffect : function(){ + afterEffect : function(anim){ this.syncShadow(); - this.el.removeClass('x-panel-animated'); + if(anim !== false){ + this.el.removeClass('x-panel-animated'); + } }, // private - wraps up an animation param with internal callbacks @@ -1378,7 +1349,7 @@ new Ext.Panel({ return; } var doAnim = animate === true || (animate !== false && this.animCollapse); - this.beforeEffect(); + this.beforeEffect(doAnim); this.onCollapse(doAnim, animate); return this; }, @@ -1391,15 +1362,15 @@ new Ext.Panel({ this.collapseDefaults)); }else{ this[this.collapseEl].hide(); - this.afterCollapse(); + this.afterCollapse(false); } }, // private - afterCollapse : function(){ + afterCollapse : function(anim){ this.collapsed = true; this.el.addClass(this.collapsedCls); - this.afterEffect(); + this.afterEffect(anim); this.fireEvent('collapse', this); }, @@ -1416,7 +1387,7 @@ new Ext.Panel({ } var doAnim = animate === true || (animate !== false && this.animCollapse); this.el.removeClass(this.collapsedCls); - this.beforeEffect(); + this.beforeEffect(doAnim); this.onExpand(doAnim, animate); return this; }, @@ -1429,15 +1400,15 @@ new Ext.Panel({ this.expandDefaults)); }else{ this[this.collapseEl].show(); - this.afterExpand(); + this.afterExpand(false); } }, // private - afterExpand : function(){ + afterExpand : function(anim){ this.collapsed = false; - this.afterEffect(); - if(this.deferLayout !== undefined){ + this.afterEffect(anim); + if(Ext.isDefined(this.deferLayout)){ this.doLayout(true); } this.fireEvent('expand', this); @@ -1472,52 +1443,46 @@ new Ext.Panel({ // private onResize : function(w, h){ - if(w !== undefined || h !== undefined){ + if(Ext.isDefined(w) || Ext.isDefined(h)){ if(!this.collapsed){ - if(typeof w == 'number'){ - w = this.adjustBodyWidth(w - this.getFrameWidth()); - if(this.tbar){ - this.tbar.setWidth(w); - if(this.topToolbar){ - this.topToolbar.setSize(w); - } + // First, set the the Panel's body width. + // If we have auto-widthed it, get the resulting full offset width so we can size the Toolbars to match + // The Toolbars must not buffer this resize operation because we need to know their heights. + + if(Ext.isNumber(w)){ + this.body.setWidth(w = this.adjustBodyWidth(w - this.getFrameWidth())); + } else if (w == 'auto') { + w = this.body.setWidth('auto').dom.offsetWidth; + } else { + w = this.body.dom.offsetWidth; + } + + if(this.tbar){ + this.tbar.setWidth(w); + if(this.topToolbar){ + this.topToolbar.setSize(w); } - if(this.bbar){ - this.bbar.setWidth(w); - if(this.bottomToolbar){ - this.bottomToolbar.setSize(w); + } + if(this.bbar){ + this.bbar.setWidth(w); + if(this.bottomToolbar){ + this.bottomToolbar.setSize(w); + // The bbar does not move on resize without this. + if (Ext.isIE) { + this.bbar.setStyle('position', 'static'); + this.bbar.setStyle('position', ''); } } + } + if(this.footer){ + this.footer.setWidth(w); if(this.fbar){ - var f = this.fbar, - fWidth = 1, - strict = Ext.isStrict; - if(this.buttonAlign == 'left'){ - fWidth = w - f.container.getFrameWidth('lr'); - }else{ - //center/right alignment off in webkit - if(Ext.isIE || Ext.isWebKit){ - //center alignment ok on webkit. - //right broken in both, center on IE - if(!(this.buttonAlign == 'center' && Ext.isWebKit) && (!strict || (!Ext.isIE8 && strict))){ - (function(){ - f.setWidth(f.getEl().child('.x-toolbar-ct').getWidth()); - }).defer(1); - }else{ - fWidth = 'auto'; - } - }else{ - fWidth = 'auto'; - } - } - f.setWidth(fWidth); + this.fbar.setSize(Ext.isIE ? (w - this.footer.getFrameWidth('lr')) : 'auto'); } - this.body.setWidth(w); - }else if(w == 'auto'){ - this.body.setWidth(w); } - if(typeof h == 'number'){ + // At this point, the Toolbars must be layed out for getFrameHeight to find a result. + if(Ext.isNumber(h)){ h = Math.max(0, this.adjustBodyHeight(h - this.getFrameHeight())); this.body.setHeight(h); }else if(h == 'auto'){ @@ -1534,13 +1499,29 @@ new Ext.Panel({ this.on('expand', function(){ delete this.queuedExpand; this.onResize(this.queuedBodySize.width, this.queuedBodySize.height); - this.doLayout(); }, this, {single:true}); } } - this.fireEvent('bodyresize', this, w, h); + this.onBodyResize(w, h); } this.syncShadow(); + Ext.Panel.superclass.onResize.call(this); + }, + + // private + onBodyResize: function(w, h){ + this.fireEvent('bodyresize', this, w, h); + }, + + // private + getToolbarHeight: function(){ + var h = 0; + if(this.rendered){ + Ext.each(this.toolbars, function(tb){ + h += tb.getHeight(); + }, this); + } + return h; }, // private @@ -1564,13 +1545,12 @@ new Ext.Panel({ * @return {Number} The frame width */ getFrameWidth : function(){ - var w = this.el.getFrameWidth('lr')+this.bwrap.getFrameWidth('lr'); + var w = this.el.getFrameWidth('lr') + this.bwrap.getFrameWidth('lr'); if(this.frame){ var l = this.bwrap.dom.firstChild; w += (Ext.fly(l).getFrameWidth('l') + Ext.fly(l.firstChild).getFrameWidth('r')); - var mc = this.bwrap.dom.firstChild.firstChild.firstChild; - w += Ext.fly(mc).getFrameWidth('lr'); + w += this.mc.getFrameWidth('lr'); } return w; }, @@ -1581,16 +1561,12 @@ new Ext.Panel({ * @return {Number} The frame height */ getFrameHeight : function(){ - var h = this.el.getFrameWidth('tb')+this.bwrap.getFrameWidth('tb'); + var h = this.el.getFrameWidth('tb') + this.bwrap.getFrameWidth('tb'); h += (this.tbar ? this.tbar.getHeight() : 0) + (this.bbar ? this.bbar.getHeight() : 0); if(this.frame){ - var hd = this.el.dom.firstChild; - var ft = this.bwrap.dom.lastChild; - h += (hd.offsetHeight + ft.offsetHeight); - var mc = this.bwrap.dom.firstChild.firstChild.firstChild; - h += Ext.fly(mc).getFrameWidth('tb'); + h += this.el.dom.firstChild.offsetHeight + this.ft.dom.offsetHeight + this.mc.getFrameWidth('tb'); }else{ h += (this.header ? this.header.getHeight() : 0) + (this.footer ? this.footer.getHeight() : 0); @@ -1628,11 +1604,16 @@ new Ext.Panel({ return this.body; }, + // private + getContentTarget : function(){ + return this.body; + }, + /** *

    Sets the title text for the panel and optionally the {@link #iconCls icon class}.

    *

    In order to be able to set the title, a header element must have been created - * for the Panel. This is triggered either by configuring the Panel with a non-blank {@link #title}, - * or configuring it with {@link #header}: true.

    + * for the Panel. This is triggered either by configuring the Panel with a non-blank {@link #title}, + * or configuring it with {@link #header}: true.

    * @param {String} title The title text to set * @param {String} iconCls (optional) {@link #iconCls iconCls} A user-defined CSS class that provides the icon image for this panel */ @@ -1661,13 +1642,13 @@ new Ext.Panel({ * @param {Object/String/Function} config A config object containing any of the following options:
    
     panel.load({
    -    url: "your-url.php",
    -    params: {param1: "foo", param2: "bar"}, // or a URL encoded string
    +    url: 'your-url.php',
    +    params: {param1: 'foo', param2: 'bar'}, // or a URL encoded string
         callback: yourFunction,
         scope: yourObject, // optional scope for the callback
         discardUrl: false,
         nocache: false,
    -    text: "Loading...",
    +    text: 'Loading...',
         timeout: 30,
         scripts: false
     });
    @@ -1685,32 +1666,44 @@ panel.load({
     
         // private
         beforeDestroy : function(){
    +        Ext.Panel.superclass.beforeDestroy.call(this);
             if(this.header){
                 this.header.removeAllListeners();
    -            if(this.headerAsText){
    -                Ext.Element.uncache(this.header.child('span'));
    -            }
             }
    -        Ext.Element.uncache(
    -            this.header,
    -            this.tbar,
    -            this.bbar,
    -            this.footer,
    -            this.body,
    -            this.bwrap
    -        );
             if(this.tools){
                 for(var k in this.tools){
                     Ext.destroy(this.tools[k]);
                 }
             }
    -        if(this.buttons){
    -            for(var b in this.buttons){
    -                Ext.destroy(this.buttons[b]);
    +        if(Ext.isArray(this.buttons)){
    +            while(this.buttons.length) {
    +                Ext.destroy(this.buttons[0]);
                 }
             }
    -        Ext.destroy(this.toolbars);
    -        Ext.Panel.superclass.beforeDestroy.call(this);
    +        if(this.rendered){
    +            Ext.destroy(
    +                this.ft,
    +                this.header,
    +                this.footer,
    +                this.toolbars,
    +                this.tbar,
    +                this.bbar,
    +                this.body,
    +                this.mc,
    +                this.bwrap
    +            );
    +            if (this.fbar) {
    +                Ext.destroy(
    +                    this.fbar,
    +                    this.fbar.el
    +                );
    +            }
    +        }else{
    +            Ext.destroy(
    +                this.topToolbar,
    +                this.bottomToolbar
    +            );
    +        }
         },
     
         // private