| Authors: | Becky Gibson
Peter Higgins Bill Keese Nikolai Onken Marcus Reimann |
|---|---|
| Developers: | ?- |
| since: | V? |
| jsDoc: | http://api.dojotoolkit.org/jsdoc/HEAD/dijit.layout.TabContainer |
Contents
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.
You can use tabs in your own application and style them as you want, but they also fit perfectly into the dijit.layout system.
First, we'll demonstrate a programmatic TabContainer creation. Note that the tabs all have a fixed height.
require(["dijit/layout/TabContainer", "dijit/layout/ContentPane", "dojo/domReady!"], function(TabContainer, ContentPane){
var tc = new TabContainer({
style: "height: 100%; width: 100%;"
}, "tc1-prog");
var cp1 = new ContentPane({
title: "Food",
content: "We offer amazing food"
});
tc.addChild(cp1);
var cp2 = new ContentPane({
title: "Drinks",
content: "We are known for our drinks."
});
tc.addChild(cp2);
tc.startup();
});
The HTML is very simple:
<div style="width: 350px; height: 290px">
<div id="tc1-prog"></div>
</div>
Here are some markup examples:
This is a plain TabContainer with three tabs and fixed height. The third tab is closable
require(["dojo/parser", "dijit/layout/TabContainer", "dijit/layout/ContentPane"]);
The HTML is very simple
<div style="width: 350px; height: 300px">
<div data-dojo-type="dijit/layout/TabContainer" style="width: 100%; height: 100%;">
<div data-dojo-type="dijit/layout/ContentPane" title="My first tab" data-dojo-props="selected:true">
Lorem ipsum and all around...
</div>
<div data-dojo-type="dijit/layout/ContentPane" title="My second tab">
Lorem ipsum and all around - second...
</div>
<div data-dojo-type="dijit/layout/ContentPane" title="My last tab" data-dojo-props="closable:true">
Lorem ipsum and all around - last...
</div>
</div>
</div>
This is a plain TabContainer with three tabs and flexible height using the doLayout="false" attribute. The second tab is closable.
require(["dojo/parser", "dijit/layout/TabContainer", "dijit/layout/ContentPane"]);
The HTML is very simple
<!-- this div is only for documentation purpose, in real development environments, just take it out -->
<div style="height: 105px;">
<div data-dojo-type="dijit/layout/TabContainer" style="width: 100%;" doLayout="false">
<div data-dojo-type="dijit/layout/ContentPane" title="My first tab" data-dojo-props="selected:true">
Lorem ipsum and all around...
</div>
<div data-dojo-type="dijit/layout/ContentPane" title="My second tab" data-dojo-props="closable:true">
Lorem ipsum and all around - second...<br />
Hmmm expanding tabs......
</div>
<div data-dojo-type="dijit/layout/ContentPane" title="My last tab">
Lorem ipsum and all around - last...<br />
<br />
<br />
Hmmm even more expanding tabs......
</div>
</div>
</div>
Normally, TabContainer will show the first Tab. But it's also possible to automatically open another Tab with giving one of the ContentPanes the argument selected: true (if programmatically created) or the attribute selected="true" (if declaratively created).
require(["dijit/layout/TabContainer", "dijit/layout/ContentPane", "dojo/domReady!"], function(TabContainer, ContentPane){
var tc = new TabContainer({
style: "height: 100%; width: 100%;"
}, "tc1-prog");
var cp1 = new ContentPane({
title: "First Tab",
content: "We offer amazing food"
});
tc.addChild(cp1);
var cp2 = new ContentPane({
title: "Second Tab",
content: "We are known for our drinks."
});
tc.addChild(cp2);
var cp3 = new ContentPane({
title: "Third Tab",
content: "This Tab has the attribute 'selected: true' set.",
selected: true
});
tc.addChild(cp3);
tc.startup();
});
The HTML is very simple:
<div style="width: 350px; height: 300px">
<div id="tc1-prog"></div>
</div>
There are several more examples of basic use cases available
Like dijit/layout/StackContainer, TabContainer works by using a simple .addChild, .removeChild, and .selectChild API, all accepting a widget to be acted upon.
require(["dijit/registry", "dijit/layout/ContentPane"], function(registry, ContentPane){
var tabs = registry.byId("myTabContainer");
var pane = new ContentPane({ title:"Remote Content", href:"remote.html" });
tabs.addChild(pane);
});
A Tab doesn't get displayed unless you call .selectChild
require(["dijit/registry", "dijit/layout/ContentPane"], function(registry, ContentPane){
var tabs = registry.byId("myTabContainer");
var pane = new ContentPane({ title:"Remote Content", href:"remote.html" });
tabs.addChild(pane);
tabs.selectChild(pane);
});
the addChild method accepts a position index, telling where in the order to add the new pane:
require(["dijit/registry", "dijit/layout/ContentPane"], function(registry, ContentPane){
var tabs = registry.byId("myTabContainer");
var pane = new ContentPane({ title:"Remote Content", href:"remote.html" });
tabs.addChild(pane, 1);
});
This will add the new remote pane after the first pane (0).
A common action for closable tabs is to register an onClose function on the child, returning true or false to indicate whether or not the closing should take place:
require(["dojo/parser", "dijit/layout/TabContainer", "dijit/layout/ContentPane", "dojo/domReady!"],
function(parser, TabContainer, ContentPane){
parser.parse();
var closablePane = new ContentPane({
title:"Close Me",
closable: true,
onClose: function(){
// confirm() returns true or false, so return that.
return confirm("Do you really want to Close this?");
}
});
onCloseEx.addChild(closablePane);
});
You can, of course, attach the onClose function directly on a pane as well:
<div style="height: 100px;">
<div data-dojo-id="onCloseEx" data-dojo-type="dijit/layout/TabContainer" style="width: 100%;" doLayout="false">
<div data-dojo-type="dijit/layout/ContentPane" title="My first tab" data-dojo-props="selected:true">
Lorem ipsum and all around...
</div>
<div data-dojo-type="dijit/layout/ContentPane" title="Other Closable" data-dojo-props="closable:true, onClose:function(){return confirm('really?');}">
... I have an in-line onClose
</div>
</div>
</div>
You can disable tabs by setting the disabled property of the pane:
pane.set("disabled", true);
Disabling a pane disables the tab button for that pane. However, it doesn't disable the pane from being programatically selected. Also, the results of disabling the currently selected pane are undefined.
<div data-dojo-type="dijit/layout/TabContainer" style="width: width: 350px; height: 200px">
<div data-dojo-type="dijit/layout/ContentPane" title="My first tab" data-dojo-props="selected:true">
Lorem ipsum and all around...
</div>
<div data-dojo-type="dijit/layout/ContentPane" id="second" title="My second tab">
Lorem ipsum and all around - second...
</div>
<div data-dojo-type="dijit/layout/ContentPane" title="My last tab" data-dojo-props="closable:true">
Lorem ipsum and all around - last...
</div>
</div>
<script type="dojo/require">
registry: "dijit/registry"
</script>
<button type=button onclick="registry.byId('second').set('disabled', !registry.byId('second').get('disabled'));">
toggle tab #2 disabled
</button>
To monitor when a pane is selected (and the previous pane is deselected), the preferred method is to use watch():
myTabContainer.watch("selectedChildWidget", function(name, oval, nval){
console.log("selected child changed from ", oval, " to ", nval);
});
To monitor when children are added/deleted, use dojo/aspect or dojo.connect:
require(["dijit/registry"], function(registry){
// assuming the same id="bar" TabContainer
var tabs = registry.byId("bar");
dojo.connect(tabs, "addChild", function(child){
console.log("just added: ", child);
});
});
It is worth noting: if you need a function to be called absolutely every time a child is added to a TabContainer (or StackContainer), you need to listen to the :ref:setupChild function to ensure you are notified of the children already existing in markup. This is only relevant if you are subclassing, for example:
require(["dojo/_base/declare", "dijit/layout/TabContainer"], function(declare, TabContainer){
declare("my.TabContainer", TabContainer, {
_setupChild: function(child){
this.inherited(arguments);
console.log("I've seen: ", child);
}
});
});
This is because addChild will not be called for the initial panes, specified in markup.
| Action | Key |
|---|---|
| Navigate to next tab button | Right arrow |
| Navigate to previous tab button | Left arrow |
| Navigate to first tab button | Home |
| Navigate to last tab button | End |
| Navigate into page | Tab |
| Navigate to next page | Ctrl + page down, ctrl + tab (FF and IE6 only) |
| Navigate to previous page | Ctrl + page up, ctrl + shift + tab (FF and IE6 only) |
| Delete a tab | With focus on the tab title of the tab to delete, press Delete or ctrl + w. Note that the tab must have been created with deletion enabled via the closable attribute. For 1.1 and later releases, pressing shift-F10 with focus on the tab title or right mouse clicking on the tab title will bring up a context menu with the option to Close the tab. This provides a mechanism to determine if the tab is closable. |