<divid="outer"> <divid="inner1">
Part 1 </div> <divid="inner2">
Part 2 </div> </div>
inner1 is big enough to hold the text "Part 1", inner2 is big enough to hold the text "Part 2", and outer is big enough to hold the divs. And if outer is bigger than the browser's viewport, the browser window displays a scrollbar. The web page you're reading now uses that layout, and unless your monitor is 3 feet tall (in which case, we envy you!) you see the scrollbar on the right.
But for some web pages, you want them to work with the opposite pattern, where you start with a given size, typically the browser viewport, and then partition it into smaller sections. This is the way desktop application look, for example a mail program that has a tree on the left, a list of messages in the upper right, and the message preview on the lower right.
Note that in this scenario, there's no scrollbar on the browser window itself, but if any pane is too small to display all the text it contains then it gets a scrollbar.
[inline:maildemo.png]
Layout like the picture above can be done using tables or fancy CSS (see recent
A List Apart article about CSS sizing), but that technique has it's limits... it doesn't allow things like tabs or accordions or split containers where the user can adjust the size of each pane.
Dijit Layout
Dijit has a number of layout widgets which can be combined in a hierarchy to achieve that. Every layout widget contains a list of other layout widgets, except for the "leaf" nodes in the hierarchy, which are typically ContentPanes.
How does this work in practice? You need to think about the application above in a top-down (or outside-in) way:
the screen is split into two parts. The top is a toolbar and
the bottom is split into a left section and right section
the left section has three panes one of which is shown at a time
the right section is split into two parts, a list of messages and a preview pane.
Conceptually it's a set of containers like this:
[inline:layoutblock.png]
There are three types of elements in that picture:
containers that display all their children side by side
containers that display one child at a time
leaf nodes containing content
#1 is either LayoutContainer or SplitContainer. A LayoutContainer is used when all but one of the elements is a constant size. (In this case, the toolbar is a constant size and the the bottom section takes the rest of the screen, so we will use a LayoutContainer for that, and SplitContainers for the other parts.
#2 is AccordionContainer, TabContainer, or StackContainer. They all do basically the same thing, but look different.
#3 is typically ContentPane but could be any widget. An important consideration is whether or not the widget's size is adjustable (like a ContentPane) or not (like a Toolbar). See #1 above.
So keeping those rules in mind and picking which widgets to use it will look like:
LayoutContainer
Toolbar
Horizontal Split Container
Accordion Container
ContentPane #1
ContentPane #2
ContentPane #3
Vertical Split Container
Content Pane #4
Content Pane #5
And then from there it's easy to convert to HTML. Starting from the outside:
Note that the layoutAlign arguments on the child nodes are actually processed by the parent, but the other arguments are processed by the child. A bit confusing but that's the way it works.
Note that height=width=100% means different things depending on the browser when you have padding or border, so when using those tags it's best not to have either of those. Put your padding, border, and margin on elements inside the outer layout container.
Restrictions about visibility: none of the layout widgets work if they are inside a hidden element. This is very important and a mistake many people make.
Startup call: when building widgets programmatically, you create the parent first, then add the children, and grandchildren... and finally call startup(). Startup() is called once on the top element in the hierarchy, after the whole hierarchy has been setup and the element inserted.
Accordion Container
In this container, panes are pulled up or down like window blinds by clicking the pane title. Only one
shows in full at a time.
[inline:accordion_pane.png]
Border Container (new in 1.1)
Partitions container into top/left/bottom/right/center sections with optional splitter controls so the user can adjust the dimensions. Useful (for example) to reserve the top 100px of the screen for title and navigation, and then the rest of the viewport for the contents. Note how in this case there would be just one scrollbar on the contents, rather than on the browser window itself.
[inline:border_container.png]
Content Pane
the leaves in the hierarchy. Contains arbitrary HTML.
[inline:content_pane.png]
Layout Container (deprecated in 1.1)
Arranges children into top/left/bottom/right/client sections. Useful (for example) to reserve the top 100px of the screen for title and navigation, and then the rest of the viewport for the contents. Note how in this case there would be just one scrollbar on the contents, rather than on the browser window itself.
[inline:layout_container.png]
Split Container (deprecated in 1.1)
Splits the children into sections where user can adjust the size of each section (making one section bigger makes others smaller)
[inline:split_container.png]
Stack Container
base class for TabContainer and AccordionContainer but allowing for user defined display to control which pane is shown
[inline:stack_container.png]
Tab Container
Like tabbed folders in a desk drawer, you click on a title tab to bring the corresponding pane to the
front.
[inline:tab_container.png]
AccordionContainer
Like StackContainer and TabContainer, an AccordionContainer holds a set of panes whose titles are all visible, but only one pane's content is visible at a time. Clicking on a pane title slides the currently-displayed one away, similar to a garage door.
Examples
For this example, we'll show the lazy-loading feature of panes. Lazy loading defers the loading process until the pane is actually displayed. Since Dojo does this with XHR, you can only load panes that reside on the server from which the original content came. We'll use a test pane provided with Dijit. You can download this file from the nightly build at http://svn.dojotoolkit.org/dojo/dijit/trunk/tests/layout/tab1.html. For the example to work verbatim, just place it in the same directory as this file on your web server.
Nunc consequat nisi vitae quam. Suspendisse sed nunc. Proin ...
Holds a set of AccordionPane widgets and displays the title of every pane, but only one pane is visible at a time. Switching between panes is visualized by sliding the other panes up/down.
Attributes
duration
Integer 250
Amount of time (in ms) it takes for panes to slide
Process the given child widget, inserting its dom node as
a child of our dom node
back()
New for 1.0Select previous page.
closeChild(/*Widget*/ page)
Close the given widget, like clicking the X button
forward()
New for 1.0Select next page.
Widget[] getChildren()
returns array of children widgets
Widget getNextSibling()
returns the widget "to the right"
Widget getParent()
returns the parent widget of this widget, assuming the parent implements dijit._Container
Widget getPreviousSibling()
returns the widget "to the left"
Boolean hasChildren()
true if this widget has child widgets
removeChild(/*Widget*/ page)
removes the passed widget instance from this widget but does not destroy it
resize(/* Object */ args)
Explicitly set this widget size (in pixels), and then call layout() to resize contents (and maybe adjust child widgets). Args is of form {w: int, h: int, l: int, t: int}.
selectChild(/*Widget*/ page)
Show the given widget (which must be one of my children)
dijit.layout.AccordionPane
AccordionPane is a ContentPane with a title. Indirect loading with the href property is supported. Nested Dijit layout widgets inside AccordionPane, such as SplitContainer, are not supported at this time.
Accessibility
Keyboard
Action
Key
Navigate to next title
Right or down arrow
Navigate to previous title
Left or up arrow
Navigate into page
Tab
Navigate to next page
Ctrl + page down, ctrl + tab (except IE7)
Navigate to previous page
Ctrl + page up
BorderContainer (1.1)
New in 1.1
This widget is a container partitioned into up to five regions: left (or leading), right (or trailing), top, and bottom with a mandatory center to fill in any remaining space. Each edge region may have an optional splitter user interface for manual resizing. Note that there can be at most one child marked for each region.
Sizes are specified for the edge regions in pixels or percentage using CSS -- height to top and bottom, width for the sides. You might specify a top region of height:100px and a left region of width:50%. The center typically does not have any dimensions specified in CSS and resizes automatically to fill the remaining space.
BorderContainer operates in a choice of two layout modes: the design attribute may be set to "headline" (by default) or "sidebar". With the "headline" layout, the top and bottom sections extend the entire width of the box and the remaining regions are placed in the middle. With the "sidebar" layout, the side panels take priority, extending the full height of the box.
A simple layout with design="headline": (demo not functional yet)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <metahttp-equiv="Content-Type"content="text/html; charset=UTF-8"> <title>Layout Container Demo 2</title> <styletype="text/css">
@import "http://o.aolcdn.com/dojo/1.1/dijit/themes/tundra/tundra.css";
@import "http://o.aolcdn.com/dojo/1.1/dojo/resources/dojo.css" </style> <scripttype="text/javascript"src="http://o.aolcdn.com/dojo/1.1/dojo/dojo.xd.js"
djConfig="parseOnLoad: true"></script> <style>
/* NOTE: for a full screen layout, must set body size equal to the viewport. */
html, body { height: 100%; width: 100%; margin: 0; padding: 0; } </style> <scripttype="text/javascript">
dojo.require("dojo.parser");
dojo.require("dijit.layout.ContentPane");
dojo.require("dijit.layout.BorderContainer"); </script> </head> <bodyclass="tundra"> <div dojoType="dijit.layout.BorderContainer" design="headline"> <div dojoType="dijit.layout.ContentPane" region="top"style="background-color:red">
The Dojo Book </div> <div dojoType="dijit.layout.ContentPane" region="left" style="background-color:lightblue;width: 120px;">
Table of Contents </div> <div dojoType="dijit.layout.ContentPane" region="center" style="background-color:yellow"> <blockquote><ahref="../node/717">Introduction</a> <ol> <li><ahref="../node/718">Dojo: What is It?</a></li> <li><ahref="../node/719">History</a></li> <li><ahref="../node/733">What Dojo Gives You</a></li> </ol> </blockquote> </div> </div> </body></html>
[TODO: sidebar demo]
Splitters can be enabled on any of the regions, except the center, by setting the "splitter" attribute on the child widget to true. "minSize" and "maxSize" attributes on the regions can specify constraints for the splitter in pixels. The "liveSplitters" attribute on the BorderContainer enables behavior where the splitter actively resizes the regions as the user moves the mouse. If set to false, the resize will only occur on mouse up.
[TODO: splitter demo]
The "persist" attribute makes it possible for the widget to remember the splitter positions from one session to the next using cookies.
BiDi considerations
Because this widget is BiDi aware, "leading" or "trailing" terminology may be used to indicate that the layout should be flipped horizontally for right-to-left rendering. "left" and "right" are absolute positions and will be unaffected by text direction.
Accessibility (a11y)
The children of BorderContainer must be listed in their natural tab order.
1.0 Migration Tips
This widget replaces the functionality of LayoutContainer and SplitContainer. The most important things to note when migrating your code from these widgets are:
LayoutContainer.layoutAlign attribute corresponds to BorderContainer.region
What LayoutContainer called the "client" region, BorderContainer calls "center"
There must be at least one child marked as region="center"
sizeShare is no longer supported. Specify the pane sizes using CSS instead as pixels or percentages.
Unlike LayoutContainer, BorderContainer does not allow for multiple widgets to be placed in a given position (e.g. inner left and outer left, patterned after Delphi) In order to achieve this, nested BorderContainers must be used.
Also, while you can specify sizes in percentages, these are only initial sizes, so setting left and right to 33% will split the children across into thirds, but resizing will allow the center to grow or shrink while the sizes remain fixed. There currently is no widget to provide equal layout, although HTML Tables may serve this purpose.
Resizing and Layouts
Involved Mixins
Your widget will have to have dijit._Contained mixed in, and dijit._Container if you plan to put other widgets inside of it. Being a container means that the getChildren function will be available to you for use when passing down the resize events.
How Layout Widgets Communicate
A container will call the resize function on its contained widgets (that should also be its direct children to avoid ambiguous layout). They might pass a size object, and the conditions in which they will are outlined below.
2 Modes of Positioning
In many browsers, an easy method of making a block node fill up the entire area of its parent container (parent container referring to any node positioned using the relative or absolution value) is to position it absolutely, and set its top, right, bottom, and left positions to 0. This isn't true for all browsers or all nodes. Because of this, it can be confusing knowing how your resize function should work.
The resize Function
If you receive a size object (which has t, l, w, and h properties representing top, left, width, and height) then it probably means that your layout has encountered a situation in which CSS is no longer capable of handling positioning. What this means is that you'll have to alter this object according to the unique properties (most likely padding and offsets) before passing the value to contained widgets. You'll also use this object to size the widget's node using either dojo.marginBox as a setter, or setting the style properties directly.
If you don't receive a size object, it probably means that you can make adjustments using only CSS. For example, if you change the style attribute top in this situation, the height automatically changes, while in non-CSS mode, you would probably end up pushing your node down, without its height changing.
ContentPane
A Content Pane is the most basic layout tile. Conceptually, it's like the content boxes in portals like MyYahoo. A content pane resembles an iframe, but contains extra design features, fits in with the current theme, and renders widgets properly.
You can use content panes by themselves, but usually you will place content panes inside of a layout container. For example, in a tabbed layout, content pane tags surround each tab of information.
Examples
Simple content panes have their content inside the tags Most of the time, these simple panes are used inside layout containers, so the examples in LayoutContainer, StackContainer and TabContainer illustrate their use.
Linked content panes, those with their content in a separate URL, are useful even without containers. To illustrate, we'll use the example data store countries.txt, which you can download below (after this page text, and right above the navigation bars). For the example to work verbatim, just place it in the same directory as these files on your web server.
If the following is linked_content_pane.html:
<!-- Note, you don't have to include Dojo scripts, CSS, or other things here ... --> <div dojoType="dojo.data.ItemFileReadStore" jsId="continentStore"
url="countries.txt"></div> <div dojoType="dijit.Tree"id="mytree" store="continentStore" query="{type:'continent'}"
labelAttr="name" typeAttr="type"></div>
You can include it within a page like this. Because the tree may take a long time to load, we display a loading message for the user.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <metahttp-equiv="Content-Type"content="text/html; charset=UTF-8"> <title>Linked Content Pane Demo</title> <styletype="text/css">
@import "http://o.aolcdn.com/dojo/1.0.0/dijit/themes/tundra/tundra.css";
@import "http://o.aolcdn.com/dojo/1.0.0/dojo/resources/dojo.css" </style> <scripttype="text/javascript"src="http://o.aolcdn.com/dojo/1.0.0/dojo/dojo.xd.js"
djConfig="parseOnLoad: true"></script> <scripttype="text/javascript">
dojo.require("dojo.parser");
dojo.require("dijit.layout.ContentPane");
dojo.require("dijit.Tree");
dojo.require("dojo.data.ItemFileReadStore"); </script> </head> <bodyclass="tundra"> <div preload="true" dojoType="dijit.layout.ContentPane"href="linked_content_pane.html">
This text be replaced with the tree </div> </body></html>
Note here that the dojo.require for the tree is placed in the calling html. SCRIPT tags of type "text/Javascript" in the included html file are ignored. However SCRIPT tags with type dojo/method
and dojo/connect work fine. See
Understanding the Parser for details.
Like all Dijit components, you can create a ContentPane dynamically. The following example adds a new ContentPane to an existing Tab Container.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <metahttp-equiv="Content-Type"content="text/html; charset=UTF-8"> <title>Content Pane Programmatic Demo</title> <styletype="text/css">
@import "http://o.aolcdn.com/dojo/1.0.0/dijit/themes/tundra/tundra.css";
@import "http://o.aolcdn.com/dojo/1.0.0/dojo/resources/dojo.css" </style> <scripttype="text/javascript"src="http://o.aolcdn.com/dojo/1.0.0/dojo/dojo.xd.js"
djConfig="parseOnLoad: true"></script> <scripttype="text/javascript">
dojo.require("dijit.layout.ContentPane");
dojo.require("dijit.layout.TabContainer");
dojo.require("dijit.Tree");
dojo.require("dojo.data.ItemFileReadStore");
dojo.addOnLoad(function() {
// create a ContentPane
var newChild =
new dijit.layout.ContentPane({
href:'linked_content_pane.html',
title:'newChild',
refreshOnShow:true
},
dojo.doc.createElement('div')
);
// find my tabContainer and add our new ContentPane
dijit.byId('myTabContainer').addChild(newChild);
// find parent Container and subscribe to selectChild event
// without it refreshOnShow and href load wont work.
newChild.startup();
}); </script> </head> <bodyclass="tundra"> <divid="myTabContainer" dojoType="dijit.layout.TabContainer" style="width:500px;height:300px"></div> </body></html>
NOTE! You must include a sourcenode when creating a ContentPane. You must call .startup() after you have addChild() it to your parent
dijit.layout.ContentPane
A widget that acts as an all-purpose sizable pane without navigation, and includes a ajax interface
Attributes
errorMessage
String Locale dep.
Message that shows if an error occurs
extractContent
Boolean false
Extract visible content from inside of <body> .... </body>
href
String
The href of the content that displays now. Set this at construction if you want to load data externally when the pane is shown. (Set preload=true to load it immediately.) Changing href after creation does not have any effect; see setHref();
isLoaded
Boolean false
Tells loading status see onLoad|onUnload for event hooks
loadingMessage
String Locale dep.
Message that shows while downloading
parseOnLoad
Boolean true
parse content and create the widgets, if any
preload
Boolean false
Force load of data even if pane is hidden.
preventCache
Boolean false
Cache content retreived externally
refreshOnShow
Boolean false
Refresh (re-download) content when pane goes from hidden to shown
Methods
cancel()
Cancels a inflight download of content
refresh()
Force a refresh (re-download) of content, be sure to turn off cache we return result of _prepareLoad here to avoid code dup. in dojox.layout.ContentPane
resize(/* String */size
Explicitly set this widget size (in pixels), and then call layout() to resize contents (and maybe adjust child widgets)
setContent(/*String|DomNode|Nodelist*/data)
Replaces old content with data content, include style classes from old content
setHref(/*String|Uri*/ href)
Reset the (external defined) content of this pane and replace with new url Note: It delays the download until widget is shown if preload is false
Extension Points
onContentError(/*Error*/ error)
called on DOM faults, require fault etc in content default is to display errormessage inside pane
onDownloadEnd()
called when download is finished
onDownloadError(/*Error*/ error)
Called when download error occurs, default is to display errormessage inside pane. Overide function to change that. The string returned by this function will be the html that tells the user a error happend
onDownloadStart()
called before download starts the string returned by this function will be the html that tells the user we are loading something override with your own function if you want to change text
onLoad(/* Event */e)
Event hook, is called after everything is loaded and widgetified
onUnload(/* Event */e)
Event hook, is called before old content is cleared
Accessibility - updated for 1.0
General Issues
The developer is responsible for determining if the ContentPane should be in the tab order of the page or not. If the ContentPane is not likely to have a focusable item within the contents, the developer may want to add tabindex=""0" onto the ContentPane element. This will put the ContentPane into the tab order so if someone is using the tab key to navigate through the elements on the page, the ContentPane itself will get focus. Having focus go to the ContentPane itself can be helpful for users of assistive technology to be able to navigate to an area that may not have any focusable elements within it such as a preview pane for mail messages or a page footer containing important information.
LayoutContainer
Similar to a layout pane in Java AWT and Delphi, a LayoutContainer is a box with a specified size (like style="width: 500px; height: 500px;"),
that contains children widgets marked with "layoutAlign" of "left", "right", "bottom", "top", and "client".
It takes it's children marked as left/top/bottom/right, and lays them out along the edges of the box,
and then it takes the child marked "client" and puts it into the remaining space in the middle.
Left/right positioning is similar to CSS's "float: left" and "float: right", and top/bottom positioning would be similar to "float: top" and "float: bottom", if there were such CSS.
Note that there can only be one client element, but there can be multiple left, right, top, or bottom elements.
Examples
A Layout Container easily formats a table of contents:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <metahttp-equiv="Content-Type"content="text/html; charset=UTF-8"> <title>Layout Container Demo 2</title> <styletype="text/css">
@import "http://o.aolcdn.com/dojo/1.0.0/dijit/themes/tundra/tundra.css";
@import "http://o.aolcdn.com/dojo/1.0.0/dojo/resources/dojo.css" </style> <scripttype="text/javascript"src="http://o.aolcdn.com/dojo/1.0.0/dojo/dojo.xd.js"
djConfig="parseOnLoad: true"></script> <style>
/* NOTE: for a full screen layout, must set body size equal to the viewport. */
html, body { height: 100%; width: 100%; margin: 0; padding: 0; } </style> <scripttype="text/javascript">
dojo.require("dojo.parser");
dojo.require("dijit.layout.ContentPane");
dojo.require("dijit.layout.LayoutContainer"); </script> </head> <bodyclass="tundra"> <div dojoType="dijit.layout.LayoutContainer"style="width: 100%; height: 100%; padding: 0; margin: 0; border: 0;"> <div dojoType="dijit.layout.ContentPane" layoutAlign="top"style="background-color:red">
The Dojo Book </div> <div dojoType="dijit.layout.ContentPane" layoutAlign="left" style="background-color:lightblue;width: 120px;">
Table of Contents </div> <div dojoType="dijit.layout.ContentPane" layoutAlign="client" style="background-color:yellow"> <blockquote><ahref="../node/717">Introduction</a> <ol> <li><ahref="../node/718">Dojo: What is It?</a></li> <li><ahref="../node/719">History</a></li> <li><ahref="../node/733">What Dojo Gives You</a></li> </ol> </blockquote> </div> </div> </body></html>
To change the drawing order:
The LayoutContainer goes through the children as specified, and each child is laid out into the "remaining space", where "remaining space" is initially
the content area of this widget, but is reduced to a smaller rectangle each time a child is added.
So, changing the order of the children will change how they are laid out.
Process the given child widget, inserting its dom node as
a child of our dom node
Widget[] getChildren()
returns array of children widgets
Widget getParent()
returns the parent widget of this widget, assuming the parent implements dijit._Container
removeChild(/*Widget*/ page)
removes the passed widget instance from this widget but does not destroy it
resize(/* Object */ args)
Explicitly set this widget size (in pixels), and then call layout() to resize contents (and maybe adjust child widgets). Args is of form {w: int, h: int, l: int, t: int}.
SplitContainer
Contains multiple children widgets, all of which are displayed side by side (either horizontally or vertically); there's a bar between each of the children, and you can adjust the relative size of each child by dragging the bars. You must specify a size (width and height) for the SplitContainer.
Dojo is an Open Source DHTML toolkit written in JavaScript. It
builds on several contributed code bases (nWidgets, Burstlib, f(m)),
which is
why we refer to it sometimes as a "unified" toolkit. Dojo aims to
solve some long-standing historical problems with DHTML which
prevented mass adoption of dynamic web application development.
</div> <div dojoType="dijit.layout.ContentPane" sizeMin="50" sizeShare="50"> <b>Swedish Chef Translation</b>
Duju is un Oopee Suoorce-a DHTML tuulkeet vreettee in JefeScreept.
Um de hur de hur de hur. It booeelds oon seferel cuntreebooted
cude-a beses (nVeedgets, Boorstleeb, f(m)),
vheech is vhy ve-a reffer tu it sumeteemes es
a "uneeffied" tuulkeet. Um de hur de hur de hur.
Duju eeems tu sulfe-a sume-a lung-stundeeng heesturicel
prublems veet DHTML vheech prefented mess edupshun
ooff dynemeec veb eppleeceshun defelupment. Um de hur de
hur de hur.
</div> </div> </body></html>
dijit.layout.SplitContainer
Container with resizable dividers.
Attributes
activeSizing
Boolean false
If true, the children's size changes as you drag the bar; otherwise, the sizes don't change until you drop the bar (by mouse-up)
orientation
String horizontal
either 'horizontal' or vertical; indicates whether the children are arranged side-by-side or up/down.
Process the given child widget, inserting its dom node as
a child of our dom node
Widget[] getChildren()
returns array of children widgets
Widget getParent()
returns the parent widget of this widget, assuming the parent implements dijit._Container
removeChild(/*Widget*/ page)
removes the passed widget instance from this widget but does not destroy it
resize(/* Object */ args)
Explicitly set this widget size (in pixels), and then call layout() to resize contents (and maybe adjust child widgets). Args is of form {w: int, h: int, l: int, t: int}.
Sizing
sizeShare
Setting the sizeShare attribute on any child widgets of a SplitContainer sets the initial relative size of that widget, either its height or width depending on the layout of the SplitContainer. The value of sizeShare is not a percentage or a pixel measure. Its value is relative to other child widgets of the same SplitContainer. So, for example, given four child widgets and each having a sizeShare attribute of 25, would evenly divide the SplitContainer into four parts. However, giving each a sizeShare attribute of 10 or 1 would achieve the same result, as the values are computed relative to each other - they do not have to add up to 100.
sizeMin
Setting the sizeMin attribute on any child widget of a SplitContainer defines the smallest size, in pixels, that the child widget will be changed to. The value is specified as an integer, without "px" appended to it.
Accessibility (added for 1.0)
Keyboard
In Dojo 1.0 there is no keyboard mechanism to resize the split container. In Firefox the content panes within a split container will be in the tab order (this is default FF behavior) so if the data is not visible, the user can use the arrow keys to scroll the data into view. This allows keyboard access to all of the data and thus accessibility requirements are met by default in Firefox. IE does not include the content pane in the tab order. If there is a chance that all of the data will not being visible within a pane of a split container, a tabindex=0 should be included in the markup of the inner content pane to ensure keyboard accessibility in both Firefox and IE.
StackContainer
A container that has multiple children, but shows only one child at a time (like looking at the pages in a book one by one). This container is good for wizards, slide shows, and long lists or text blocks.
Examples
Here's a freely pageable document.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License. "The Library" refers to a covered work governed by
this License, other than an Application or a Combined Work as defined below.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <metahttp-equiv="Content-Type"content="text/html; charset=UTF-8"> <title>Stack Container Demo</title> <styletype="text/css">
@import "http://o.aolcdn.com/dojo/1.0.0/dijit/themes/tundra/tundra.css";
@import "http://o.aolcdn.com/dojo/1.0.0/dojo/resources/dojo.css" </style> <scripttype="text/javascript"src="http://o.aolcdn.com/dojo/1.0.0/dojo/dojo.xd.js"
djConfig="parseOnLoad: true"></script> <scripttype="text/javascript">
dojo.require("dojo.parser");
dojo.require("dijit.layout.ContentPane");
dojo.require("dijit.layout.StackContainer");
dojo.require("dijit.form.Button"); </script> </head> <bodyclass="tundra"> <buttonid="previous"onClick="dijit.byId('mainTabContainer').back()"><</button> <buttonid="next"onClick="dijit.byId('mainTabContainer').forward()">></button> <divid="mainTabContainer" dojoType="dijit.layout.StackContainer" style="width: 90%; border:1px solid #9b9b9b; height: 20em;
margin: 0.5em 0 0.5em 0; padding: 0.5em;"> <pid="Page1" dojoType="dijit.layout.ContentPane"label="Intro">
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
<pid="Page2" dojoType="dijit.layout.ContentPane">
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License. "The Library" refers to a covered work governed by
this License, other than an Application or a Combined Work as defined below.
<pid="Page3" dojoType="dijit.layout.ContentPane">
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
</div> </body></html>
Indication of the current child
As standard, there are no styles on the buttons associated with the StackContainer to indicate which child is currently being shown. However, Dijit adds a "dijitToggleButtonChecked" class to the button for the child being shown and we can use this class to provide styling ourselves. For example, we could use the following rules to highlight the button with a white background and, in Windows high contrast mode, a dashed border:
Process the given child widget, inserting its dom node as
a child of our dom node
back()
New for 1.0Select previous page.
forward()
New for 1.0Select next page.
Widget[] getChildren()
returns array of children widgets
Widget getNextSibling()
returns the widget "to the right"
Widget getParent()
returns the parent widget of this widget, assuming the parent implements dijit._Container
Widget getPreviousSibling()
returns the widget "to the left"
removeChild(/*Widget*/ page)
removes the passed widget instance from this widget but does not destroy it
resize(/* Object */ args)
Explicitly set this widget size (in pixels), and then call layout() to resize contents (and maybe adjust child widgets). Args is of form {w: int, h: int, l: int, t: int}.
selectChild(/*Widget*/ page)
Show the given widget (which must be one of my children)
Accessibility
Keyboard
Action
Key
Navigate to next tab button
Right arrow
Navigate to previous tab button
Left arrow
Navigate into page
Tab
Navigate to next page
Ctrl + page down, ctrl + tab (except IE7)
Navigate to previous page
Ctrl + page up
Delete a tab
Delete, ctrl + w (updated for 1.0 - delete is not supported in stack container)
TabContainer
A TabContainer is a container that has multiple panes, but shows only
one pane at a time. There are a set of tabs corresponding to each pane,
where each tab has the title (aka label) of the pane, and optionally a close button.
Examples
Here's a Grimm set of tabs, indeed.
Once upon a time there was a dear little girl who was loved by
every one who looked at her, but most of all by her grandmother,
and there was nothing that she would not have given to the child.
Hard by a great forest dwelt a poor wood-cutter with his wife
and his two children. The boy was called Hansel and the girl Gretel.
He had little to bite and to break, and once when great dearth fell
on the land, he could no longer procure even daily bread.
There was once upon a time a hermit who lived in a forest at the foot
of a mountain, and passed his time in prayer and good works,
and every evening he carried, to the glory of God, two pails of water
up the mountain.