- Author:
- David Nickerson <nickerso@users.sourceforge.net>
- Date:
- 2009-07-16 02:00:03+12:00
- Desc:
- the starting point for the HH tutorial example
- Permanent Source URI:
- https://models.fieldml.org/workspace/a1/rawfile/f6a8f90307388eb4b040ee3566b84d88b59247f7/dojo-presentation/js/dojo/dijit/layout/AccordionContainer.js
dojo.provide("dijit.layout.AccordionContainer");
dojo.require("dojo.fx");
dojo.require("dijit._Container");
dojo.require("dijit._Templated");
dojo.require("dijit.layout.StackContainer");
dojo.require("dijit.layout.ContentPane");
dojo.declare(
"dijit.layout.AccordionContainer",
dijit.layout.StackContainer,
{
// summary:
// Holds a set of panes where every pane's title is visible, but only one pane's content is visible at a time,
// and switching between panes is visualized by sliding the other panes up/down.
// example:
// | <div dojoType="dijit.layout.AccordionContainer">
// | <div dojoType="dijit.layout.AccordionPane" title="pane 1">
// | <div dojoType="dijit.layout.ContentPane">...</div>
// | </div>
// | <div dojoType="dijit.layout.AccordionPane" title="pane 2">
// | <p>This is some text</p>
// || ...
// | </div>
//
// duration: Integer
// Amount of time (in ms) it takes to slide panes
duration: dijit.defaultDuration,
_verticalSpace: 0,
baseClass: "dijitAccordionContainer",
postCreate: function(){
this.domNode.style.overflow = "hidden";
this.inherited(arguments);
dijit.setWaiRole(this.domNode, "tablist");
},
startup: function(){
if(this._started){ return; }
this.inherited(arguments);
if(this.selectedChildWidget){
var style = this.selectedChildWidget.containerNode.style;
style.display = "";
style.overflow = "auto";
this.selectedChildWidget._setSelectedState(true);
}
},
layout: function(){
// summary:
// Set the height of the open pane based on what room remains
// get cumulative height of all the title bars, and figure out which pane is open
var totalCollapsedHeight = 0;
var openPane = this.selectedChildWidget;
dojo.forEach(this.getChildren(), function(child){
totalCollapsedHeight += child.getTitleHeight();
});
var mySize = this._contentBox;
this._verticalSpace = mySize.h - totalCollapsedHeight;
if(openPane){
openPane.containerNode.style.height = this._verticalSpace + "px";
/***
TODO: this is wrong. probably you wanted to call resize on the SplitContainer
inside the AccordionPane??
if(openPane.resize){
openPane.resize({h: this._verticalSpace});
}
***/
}
},
_setupChild: function(/*Widget*/ page){
// Summary: prepare the given child
return page;
},
_transition: function(/*Widget?*/newWidget, /*Widget?*/oldWidget){
//TODO: should be able to replace this with calls to slideIn/slideOut
if(this._inTransition){ return; }
this._inTransition = true;
var animations = [];
var paneHeight = this._verticalSpace;
if(newWidget){
newWidget.setSelected(true);
var newContents = newWidget.containerNode;
newContents.style.display = "";
animations.push(dojo.animateProperty({
node: newContents,
duration: this.duration,
properties: {
height: { start: 1, end: paneHeight }
},
onEnd: function(){
newContents.style.overflow = "auto";
}
}));
}
if(oldWidget){
oldWidget.setSelected(false);
var oldContents = oldWidget.containerNode;
oldContents.style.overflow = "hidden";
animations.push(dojo.animateProperty({
node: oldContents,
duration: this.duration,
properties: {
height: { start: paneHeight, end: "1" }
},
onEnd: function(){
oldContents.style.display = "none";
}
}));
}
this._inTransition = false;
dojo.fx.combine(animations).play();
},
// note: we are treating the container as controller here
_onKeyPress: function(/*Event*/ e){
if(this.disabled || e.altKey || !(e._dijitWidget || e.ctrlKey)){ return; }
var k = dojo.keys;
var fromTitle = e._dijitWidget;
switch(e.charOrCode){
case k.LEFT_ARROW:
case k.UP_ARROW:
if (fromTitle){
this._adjacent(false)._onTitleClick();
dojo.stopEvent(e);
}
break;
case k.PAGE_UP:
if (e.ctrlKey){
this._adjacent(false)._onTitleClick();
dojo.stopEvent(e);
}
break;
case k.RIGHT_ARROW:
case k.DOWN_ARROW:
if (fromTitle){
this._adjacent(true)._onTitleClick();
dojo.stopEvent(e);
}
break;
case k.PAGE_DOWN:
if (e.ctrlKey){
this._adjacent(true)._onTitleClick();
dojo.stopEvent(e);
}
break;
default:
if(e.ctrlKey && e.charOrCode == k.TAB){
this._adjacent(e._dijitWidget, !e.shiftKey)._onTitleClick();
dojo.stopEvent(e);
}
}
}
}
);
dojo.declare("dijit.layout.AccordionPane",
[dijit.layout.ContentPane, dijit._Templated, dijit._Contained],
{
// summary:
// AccordionPane is a ContentPane with a title that may contain another widget.
// Nested layout widgets, such as SplitContainer, are not supported at this time.
// example:
// | see dijit.layout.AccordionContainer
templatePath: dojo.moduleUrl("dijit.layout", "templates/AccordionPane.html"),
baseClass: "dijitAccordionPane",
postCreate: function(){
this.inherited(arguments)
dojo.setSelectable(this.titleNode, false);
this.setSelected(this.selected);
dojo.attr(this.titleTextNode, "id", this.domNode.id+"_title");
dijit.setWaiState(this.focusNode, "labelledby", dojo.attr(this.titleTextNode, "id"));
},
getTitleHeight: function(){
// summary: returns the height of the title dom node
return dojo.marginBox(this.titleNode).h; // Integer
},
_onTitleClick: function(){
// summary: callback when someone clicks my title
var parent = this.getParent();
if(!parent._inTransition){
parent.selectChild(this);
dijit.focus(this.focusNode);
}
},
_onTitleEnter: function(){
// summary: callback when someone hovers over my title
dojo.addClass(this.focusNode, "dijitAccordionTitle-hover");
},
_onTitleLeave: function(){
// summary: callback when someone stops hovering over my title
dojo.removeClass(this.focusNode, "dijitAccordionTitle-hover");
},
_onTitleKeyPress: function(/*Event*/ evt){
evt._dijitWidget = this;
return this.getParent()._onKeyPress(evt);
},
_setSelectedState: function(/*Boolean*/ isSelected){
this.selected = isSelected;
dojo[(isSelected ? "addClass" : "removeClass")](this.titleNode,"dijitAccordionTitle-selected");
dijit.setWaiState(this.focusNode, "expanded", isSelected);
this.focusNode.setAttribute("tabIndex", isSelected ? "0" : "-1");
},
_handleFocus: function(/*Event*/e){
// summary: handle the blur and focus state of this widget
dojo[(e.type=="focus" ? "addClass" : "removeClass")](this.focusNode,"dijitAccordionFocused");
},
setSelected: function(/*Boolean*/ isSelected){
// summary: change the selected state on this pane
this._setSelectedState(isSelected);
if(isSelected){
this.onSelected();
this._loadCheck(); // if href specified, trigger load
}
},
onSelected: function(){
// summary: called when this pane is selected
}
});