<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>The source code</title>
- <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
- <script type="text/javascript" src="../prettify/prettify.js"></script>
+ <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
+ <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
<style type="text/css">
.highlight { display: block; background-color: #ddd; }
</style>
<pre class="prettyprint lang-js"><span id='Ext-layout-container-Accordion'>/**
</span> * @class Ext.layout.container.Accordion
* @extends Ext.layout.container.VBox
- * <p>This is a layout that manages multiple Panels in an expandable accordion style such that only
- * <b>one Panel can be expanded at any given time</b>. Each Panel has built-in support for expanding and collapsing.</p>
- * <p>Note: Only Ext.Panels <b>and all subclasses of Ext.panel.Panel</b> may be used in an accordion layout Container.</p>
- * {@img Ext.layout.container.Accordion/Ext.layout.container.Accordion.png Ext.layout.container.Accordion container layout}
- * <p>Example usage:</p>
- * <pre><code>
-Ext.create('Ext.panel.Panel', {
- title: 'Accordion Layout',
- width: 300,
- height: 300,
- layout:'accordion',
- defaults: {
- // applied to each contained panel
- bodyStyle: 'padding:15px'
- },
- layoutConfig: {
- // layout-specific configs go here
- titleCollapse: false,
- animate: true,
- activeOnTop: true
- },
- items: [{
- title: 'Panel 1',
- html: 'Panel content!'
- },{
- title: 'Panel 2',
- html: 'Panel content!'
- },{
- title: 'Panel 3',
- html: 'Panel content!'
- }],
- renderTo: Ext.getBody()
-});
-</code></pre>
+ *
+ * This is a layout that manages multiple Panels in an expandable accordion style such that only
+ * **one Panel can be expanded at any given time**. Each Panel has built-in support for expanding and collapsing.
+ *
+ * Note: Only Ext Panels and all subclasses of Ext.panel.Panel may be used in an accordion layout Container.
+ *
+ * @example
+ * Ext.create('Ext.panel.Panel', {
+ * title: 'Accordion Layout',
+ * width: 300,
+ * height: 300,
+ * layout:'accordion',
+ * defaults: {
+ * // applied to each contained panel
+ * bodyStyle: 'padding:15px'
+ * },
+ * layoutConfig: {
+ * // layout-specific configs go here
+ * titleCollapse: false,
+ * animate: true,
+ * activeOnTop: true
+ * },
+ * items: [{
+ * title: 'Panel 1',
+ * html: 'Panel content!'
+ * },{
+ * title: 'Panel 2',
+ * html: 'Panel content!'
+ * },{
+ * title: 'Panel 3',
+ * html: 'Panel content!'
+ * }],
+ * renderTo: Ext.getBody()
+ * });
*/
Ext.define('Ext.layout.container.Accordion', {
extend: 'Ext.layout.container.VBox',
alias: ['layout.accordion'],
alternateClassName: 'Ext.layout.AccordionLayout',
-
+
+ itemCls: Ext.baseCSSPrefix + 'box-item ' + Ext.baseCSSPrefix + 'accordion-item',
+
align: 'stretch',
<span id='Ext-layout-container-Accordion-cfg-fill'> /**
</span> * @cfg {Boolean} fill
* True to adjust the active item's height to fill the available space in the container, false to use the
- * item's current height, or auto height if not explicitly set (defaults to true).
+ * item's current height, or auto height if not explicitly set.
*/
fill : true,
+
<span id='Ext-layout-container-Accordion-cfg-autoWidth'> /**
</span> * @cfg {Boolean} autoWidth
- * <p><b>This config is ignored in ExtJS 4.x.</b></p>
* Child Panels have their width actively managed to fit within the accordion's width.
+ * @deprecated This config is ignored in ExtJS 4
*/
autoWidth : true,
+
<span id='Ext-layout-container-Accordion-cfg-titleCollapse'> /**
</span> * @cfg {Boolean} titleCollapse
- * <p><b>Not implemented in PR2.</b></p>
* True to allow expand/collapse of each contained panel by clicking anywhere on the title bar, false to allow
- * expand/collapse only when the toggle tool button is clicked (defaults to true). When set to false,
+ * expand/collapse only when the toggle tool button is clicked. When set to false,
* {@link #hideCollapseTool} should be false also.
*/
titleCollapse : true,
+
<span id='Ext-layout-container-Accordion-cfg-hideCollapseTool'> /**
</span> * @cfg {Boolean} hideCollapseTool
- * True to hide the contained Panels' collapse/expand toggle buttons, false to display them (defaults to false).
+ * True to hide the contained Panels' collapse/expand toggle buttons, false to display them.
* When set to true, {@link #titleCollapse} is automatically set to <code>true</code>.
*/
hideCollapseTool : false,
+
<span id='Ext-layout-container-Accordion-cfg-collapseFirst'> /**
</span> * @cfg {Boolean} collapseFirst
* True to make sure the collapse/expand toggle button always renders first (to the left of) any other tools
- * in the contained Panels' title bars, false to render it last (defaults to false).
+ * in the contained Panels' title bars, false to render it last.
*/
collapseFirst : false,
+
<span id='Ext-layout-container-Accordion-cfg-animate'> /**
</span> * @cfg {Boolean} animate
* True to slide the contained panels open and closed during expand/collapse using animation, false to open and
- * close directly with no animation (defaults to <code>true</code>). Note: The layout performs animated collapsing
+ * close directly with no animation. Note: The layout performs animated collapsing
* and expanding, <i>not</i> the child Panels.
*/
animate : true,
<span id='Ext-layout-container-Accordion-cfg-activeOnTop'> /**
</span> * @cfg {Boolean} activeOnTop
- * <p><b>Not implemented in PR4.</b></p>
- * <p>Only valid when {@link #multi" is <code>false</code>.</p>
+ * Only valid when {@link #multi} is `false` and {@link #animate} is `false`.
+ *
* True to swap the position of each panel as it is expanded so that it becomes the first item in the container,
- * false to keep the panels in the rendered order. <b>This is NOT compatible with "animate:true"</b> (defaults to false).
+ * false to keep the panels in the rendered order.
*/
activeOnTop : false,
<span id='Ext-layout-container-Accordion-cfg-multi'> /**
</span> * @cfg {Boolean} multi
- * Defaults to <code>false</code>. Set to <code>true</code> to enable multiple accordion items to be open at once.
+ * Set to <code>true</code> to enable multiple accordion items to be open at once.
*/
multi: false,
me.callParent(arguments);
if (me.fill) {
- if (!me.owner.el.dom.style.height) {
+ if (!(me.owner.el.dom.style.height || me.getLayoutTargetSize().height)) {
return false;
}
} else {
i = 0,
comp,
targetSize = me.getLayoutTargetSize(),
- renderedPanels = [],
- border;
+ renderedPanels = [];
for (; i < ln; i++) {
comp = items[i];
delete comp.hideHeader;
comp.collapsible = true;
comp.title = comp.title || '&#160;';
- comp.setBorder(false);
// Set initial sizes
comp.width = targetSize.width;
comp.collapsed = true;
}
// Otherwise expand the first item with collapsed explicitly configured as false
- else if (comp.collapsed === false) {
+ else if (comp.hasOwnProperty('collapsed') && comp.collapsed === false) {
comp.flex = 1;
me.expandedItem = i;
} else {
comp.collapsed = true;
}
+ // If we are fitting, then intercept expand/collapse requests.
+ me.owner.mon(comp, {
+ show: me.onComponentShow,
+ beforeexpand: me.onComponentExpand,
+ beforecollapse: me.onComponentCollapse,
+ scope: me
+ });
} else {
delete comp.flex;
comp.animCollapse = me.initialAnimate;
comp.autoHeight = true;
comp.autoScroll = false;
}
+ comp.border = comp.collapsed;
}
}
if (ln && me.expandedItem === undefined) {
me.expandedItem = 0;
comp = items[0];
- comp.collapsed = false;
+ comp.collapsed = comp.border = false;
if (me.fill) {
comp.flex = 1;
}
}
-
+
// Render all Panels.
me.callParent(arguments);
-
+
// Postprocess rendered Panels.
ln = renderedPanels.length;
for (i = 0; i < ln; i++) {
comp.header.addCls(Ext.baseCSSPrefix + 'accordion-hd');
comp.body.addCls(Ext.baseCSSPrefix + 'accordion-body');
-
- // If we are fitting, then intercept expand/collapse requests.
- if (me.fill) {
- me.owner.mon(comp, {
- show: me.onComponentShow,
- beforeexpand: me.onComponentExpand,
- beforecollapse: me.onComponentCollapse,
- scope: me
- });
- }
}
},
onLayout: function() {
var me = this;
-
- me.updatePanelClasses();
-
+
+
if (me.fill) {
me.callParent(arguments);
} else {
}
}
}
-
+ me.updatePanelClasses();
+
return me;
},
-
+
updatePanelClasses: function() {
var children = this.getLayoutItems(),
ln = children.length,
siblingCollapsed = true,
i, child;
-
+
for (i = 0; i < ln; i++) {
child = children[i];
- if (!siblingCollapsed) {
- child.header.addCls(Ext.baseCSSPrefix + 'accordion-hd-sibling-expanded');
+
+ // Fix for EXTJSIV-3724. Windows only.
+ // Collapsing the Psnel's el to a size which only allows a single hesder to be visible, scrolls the header out of view.
+ if (Ext.isWindows) {
+ child.el.dom.scrollTop = 0;
}
- else {
+
+ if (siblingCollapsed) {
child.header.removeCls(Ext.baseCSSPrefix + 'accordion-hd-sibling-expanded');
}
+ else {
+ child.header.addCls(Ext.baseCSSPrefix + 'accordion-hd-sibling-expanded');
+ }
+
if (i + 1 == ln && child.collapsed) {
child.header.addCls(Ext.baseCSSPrefix + 'accordion-hd-last-collapsed');
}
siblingCollapsed = child.collapsed;
}
},
+
+ animCallback: function(){
+ Ext.Array.forEach(this.toCollapse, function(comp){
+ comp.fireEvent('collapse', comp);
+ });
+
+ Ext.Array.forEach(this.toExpand, function(comp){
+ comp.fireEvent('expand', comp);
+ });
+ },
+
+ setupEvents: function(){
+ this.toCollapse = [];
+ this.toExpand = [];
+ },
// When a Component expands, adjust the heights of the other Components to be just enough to accommodate
// their headers.
i = 0,
comp;
+ me.setupEvents();
for (; i < len; i++) {
comp = it[i];
if (comp === toExpand && comp.collapsed) {
me.setCollapsed(comp);
}
}
-
+
me.animate = me.initialAnimate;
- me.layout();
+ if (me.activeOnTop) {
+ // insert will trigger a layout
+ me.owner.insert(0, toExpand);
+ } else {
+ me.layout();
+ }
me.animate = false;
return false;
},
toExpand = comp.next() || comp.prev(),
expanded = me.multi ? me.owner.query('>panel:not([collapsed])') : [];
+ me.setupEvents();
// If we are allowing multi, and the "toCollapse" component is NOT the only expanded Component,
// then ask the box layout to collapse it to its header.
if (me.multi) {
if (expanded.length === 1 && expanded[0] === comp) {
me.setExpanded(toExpand);
}
-
+
me.animate = me.initialAnimate;
me.layout();
me.animate = false;
comp.el.setHeight(comp.height);
comp.collapsed = true;
delete comp.flex;
- comp.fireEvent('collapse', comp);
+ if (this.initialAnimate) {
+ this.toCollapse.push(comp);
+ } else {
+ comp.fireEvent('collapse', comp);
+ }
if (comp.collapseTool) {
comp.collapseTool.setType('expand-' + comp.getOppositeDirection(comp.collapseDirection));
}
comp.flex = 1;
comp.removeCls(comp.collapsedCls);
comp.header.removeCls(comp.collapsedHeaderCls);
- comp.fireEvent('expand', comp);
+ if (this.initialAnimate) {
+ this.toExpand.push(comp);
+ } else {
+ comp.fireEvent('expand', comp);
+ }
if (comp.collapseTool) {
comp.collapseTool.setType('collapse-' + comp.collapseDirection);
}