<!DOCTYPE html>
|
<html>
|
<head>
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
<title>The source code</title>
|
<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>
|
<script type="text/javascript">
|
function highlight() {
|
document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
|
}
|
</script>
|
</head>
|
<body onload="prettyPrint(); highlight();">
|
<pre class="prettyprint lang-js"><span id='Ext-layout-container-Accordion'>/**
|
</span> * This is a layout that manages multiple Panels in an expandable accordion style such that by default only
|
* one Panel can be expanded at any given time (set {@link #multi} config to have more open). 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,
|
* defaults: {
|
* // applied to each contained panel
|
* bodyStyle: 'padding:15px'
|
* },
|
* layout: {
|
* // layout-specific configs go here
|
* type: 'accordion',
|
* 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',
|
|
<span id='Ext-layout-container-Accordion-property-targetCls'> targetCls: Ext.baseCSSPrefix + 'accordion-layout-ct',
|
</span><span id='Ext-layout-container-Accordion-cfg-itemCls'> itemCls: [Ext.baseCSSPrefix + 'box-item', Ext.baseCSSPrefix + 'accordion-item'],
|
</span>
|
<span id='Ext-layout-container-Accordion-cfg-align'> align: 'stretch',
|
</span>
|
<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.
|
*/
|
fill : true,
|
|
<span id='Ext-layout-container-Accordion-cfg-autoWidth'> /**
|
</span> * @cfg {Boolean} autoWidth
|
* Child Panels have their width actively managed to fit within the accordion's width.
|
* @removed This config is ignored in ExtJS 4
|
*/
|
|
<span id='Ext-layout-container-Accordion-cfg-titleCollapse'> /**
|
</span> * @cfg {Boolean} titleCollapse
|
* 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. When set to false,
|
* {@link #hideCollapseTool} should be false also. An explicit {@link Ext.panel.Panel#titleCollapse} declared
|
* on the panel will override this setting.
|
*/
|
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.
|
* When set to true, {@link #titleCollapse} is automatically set to true.
|
*/
|
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. By default, this will use the
|
* {@link Ext.panel.Panel#collapseFirst} setting on the panel. If the config option is specified on the layout,
|
* it will override the panel value.
|
*/
|
collapseFirst : undefined,
|
|
<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. Note: The layout performs animated collapsing
|
* and expanding, *not* the child Panels.
|
*/
|
animate : true,
|
<span id='Ext-layout-container-Accordion-cfg-activeOnTop'> /**
|
</span> * @cfg {Boolean} activeOnTop
|
* 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.
|
*/
|
activeOnTop : false,
|
<span id='Ext-layout-container-Accordion-cfg-multi'> /**
|
</span> * @cfg {Boolean} multi
|
* Set to true to enable multiple accordion items to be open at once.
|
*/
|
multi: false,
|
|
<span id='Ext-layout-container-Accordion-property-defaultAnimatePolicy'> defaultAnimatePolicy: {
|
</span> y: true,
|
height: true
|
},
|
|
<span id='Ext-layout-container-Accordion-method-constructor'> constructor: function() {
|
</span> var me = this;
|
|
me.callParent(arguments);
|
|
if (!me.multi && me.animate) {
|
me.animatePolicy = Ext.apply({}, me.defaultAnimatePolicy);
|
} else {
|
me.animatePolicy = null;
|
}
|
},
|
|
<span id='Ext-layout-container-Accordion-method-beforeRenderItems'> beforeRenderItems: function (items) {
|
</span> var me = this,
|
ln = items.length,
|
i = 0,
|
owner = me.owner,
|
collapseFirst = me.collapseFirst,
|
hasCollapseFirst = Ext.isDefined(collapseFirst),
|
expandedItem = me.getExpanded(true)[0],
|
multi = me.multi,
|
comp;
|
|
for (; i < ln; i++) {
|
comp = items[i];
|
if (!comp.rendered) {
|
// Set up initial properties for Panels in an accordion.
|
if (!multi || comp.collapsible !== false) {
|
comp.collapsible = true;
|
}
|
|
if (comp.collapsible) {
|
if (hasCollapseFirst) {
|
comp.collapseFirst = collapseFirst;
|
}
|
if (me.hideCollapseTool) {
|
comp.hideCollapseTool = me.hideCollapseTool;
|
comp.titleCollapse = true;
|
} else if (me.titleCollapse && comp.titleCollapse === undefined) {
|
// Only force titleCollapse if we don't explicitly
|
// set one on the child panel
|
comp.titleCollapse = me.titleCollapse;
|
}
|
}
|
|
delete comp.hideHeader;
|
delete comp.width;
|
comp.title = comp.title || '&#160;';
|
comp.addBodyCls(Ext.baseCSSPrefix + 'accordion-body');
|
|
// If only one child Panel is allowed to be expanded
|
// then collapse all except the first one found with collapsed:false
|
// If we have hasExpanded set, we've already done this
|
if (!multi) {
|
if (expandedItem) {
|
comp.collapsed = expandedItem !== comp;
|
} else if (comp.hasOwnProperty('collapsed') && comp.collapsed === false) {
|
expandedItem = comp;
|
} else {
|
comp.collapsed = true;
|
}
|
|
// If only one child Panel may be expanded, then intercept expand/show requests.
|
owner.mon(comp, {
|
show: me.onComponentShow,
|
beforeexpand: me.onComponentExpand,
|
beforecollapse: me.onComponentCollapse,
|
scope: me
|
});
|
}
|
// Need to still check this outside multi because we don't want
|
// a single item to be able to collapse
|
owner.mon(comp, 'beforecollapse', me.onComponentCollapse, me);
|
comp.headerOverCls = Ext.baseCSSPrefix + 'accordion-hd-over';
|
}
|
}
|
|
// If no collapsed:false Panels found, make the first one expanded.
|
if (!multi) {
|
if (!expandedItem) {
|
if (ln) {
|
items[0].collapsed = false;
|
}
|
} else if (me.activeOnTop) {
|
expandedItem.collapsed = false;
|
me.configureItem(expandedItem);
|
if (owner.items.indexOf(expandedItem) > 0) {
|
owner.insert(0, expandedItem);
|
}
|
}
|
}
|
},
|
|
<span id='Ext-layout-container-Accordion-method-getItemsRenderTree'> getItemsRenderTree: function(items) {
|
</span> this.beforeRenderItems(items);
|
return this.callParent(arguments);
|
},
|
|
<span id='Ext-layout-container-Accordion-method-renderItems'> renderItems : function(items, target) {
|
</span> this.beforeRenderItems(items);
|
|
this.callParent(arguments);
|
},
|
|
<span id='Ext-layout-container-Accordion-method-configureItem'> configureItem: function(item) {
|
</span> this.callParent(arguments);
|
|
// We handle animations for the expand/collapse of items.
|
// Items do not have individual borders
|
item.animCollapse = item.border = false;
|
|
// If filling available space, all Panels flex.
|
if (this.fill) {
|
item.flex = 1;
|
}
|
},
|
|
<span id='Ext-layout-container-Accordion-method-beginLayout'> beginLayout: function (ownerContext) {
|
</span> this.callParent(arguments);
|
this.updatePanelClasses(ownerContext);
|
},
|
|
<span id='Ext-layout-container-Accordion-method-updatePanelClasses'> updatePanelClasses: function(ownerContext) {
|
</span> var children = ownerContext.visibleItems,
|
ln = children.length,
|
siblingCollapsed = true,
|
i, child, header;
|
|
for (i = 0; i < ln; i++) {
|
child = children[i];
|
header = child.header;
|
header.addCls(Ext.baseCSSPrefix + 'accordion-hd');
|
|
if (siblingCollapsed) {
|
header.removeCls(Ext.baseCSSPrefix + 'accordion-hd-sibling-expanded');
|
} else {
|
header.addCls(Ext.baseCSSPrefix + 'accordion-hd-sibling-expanded');
|
}
|
|
if (i + 1 == ln && child.collapsed) {
|
header.addCls(Ext.baseCSSPrefix + 'accordion-hd-last-collapsed');
|
} else {
|
header.removeCls(Ext.baseCSSPrefix + 'accordion-hd-last-collapsed');
|
}
|
|
siblingCollapsed = child.collapsed;
|
}
|
},
|
|
<span id='Ext-layout-container-Accordion-method-onComponentExpand'> // When a Component expands, adjust the heights of the other Components to be just enough to accommodate
|
</span> // their headers.
|
// The expanded Component receives the only flex value, and so gets all remaining space.
|
onComponentExpand: function(toExpand) {
|
var me = this,
|
owner = me.owner,
|
multi = me.multi,
|
animate = me.animate,
|
moveToTop = !multi && !me.animate && me.activeOnTop,
|
expanded,
|
expandedCount, i,
|
previousValue;
|
|
if (!me.processing) {
|
me.processing = true;
|
previousValue = owner.deferLayouts;
|
owner.deferLayouts = true;
|
expanded = multi ? [] : me.getExpanded();
|
expandedCount = expanded.length;
|
|
// Collapse all other expanded child items (Won't loop if multi is true)
|
for (i = 0; i < expandedCount; i++) {
|
expanded[i].collapse();
|
}
|
|
if (moveToTop) {
|
// Prevent extra layout when moving the item
|
Ext.suspendLayouts();
|
owner.insert(0, toExpand);
|
Ext.resumeLayouts();
|
}
|
|
owner.deferLayouts = previousValue;
|
me.processing = false;
|
}
|
},
|
|
<span id='Ext-layout-container-Accordion-method-onComponentCollapse'> onComponentCollapse: function(comp) {
|
</span> var me = this,
|
owner = me.owner,
|
toExpand,
|
expanded,
|
previousValue;
|
|
if (me.owner.items.getCount() === 1) {
|
// do not allow collapse if there is only one item
|
return false;
|
}
|
|
if (!me.processing) {
|
me.processing = true;
|
previousValue = owner.deferLayouts;
|
owner.deferLayouts = true;
|
toExpand = comp.next() || comp.prev();
|
|
// 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) {
|
expanded = me.getExpanded();
|
|
// If the collapsing Panel is the only expanded one, expand the following Component.
|
// All this is handling fill: true, so there must be at least one expanded,
|
if (expanded.length === 1) {
|
toExpand.expand();
|
}
|
|
} else if (toExpand) {
|
toExpand.expand();
|
}
|
owner.deferLayouts = previousValue;
|
me.processing = false;
|
}
|
},
|
|
<span id='Ext-layout-container-Accordion-method-onComponentShow'> onComponentShow: function(comp) {
|
</span> // Showing a Component means that you want to see it, so expand it.
|
this.onComponentExpand(comp);
|
},
|
|
<span id='Ext-layout-container-Accordion-method-getExpanded'> getExpanded: function(explicitCheck){
|
</span> var items = this.owner.items.items,
|
len = items.length,
|
i = 0,
|
out = [],
|
add,
|
item;
|
|
for (; i < len; ++i) {
|
item = items[i];
|
if (explicitCheck) {
|
add = item.hasOwnProperty('collapsed') && item.collapsed === false;
|
} else {
|
add = !item.collapsed;
|
}
|
if (add) {
|
out.push(item);
|
}
|
}
|
return out;
|
|
}
|
});</pre>
|
</body>
|
</html>
|