Using Dojo TabContainer

August 10, 2006

Dojo is a JavaScript library that makes it easier to create a more dynamic web UI. There are a number of things that we are trying to do with our UI. Therefore, instead of writing all the code ourselves, we have chosen to leverage other people’s work, i.e. debugging, and use a JavaScript library. Of the various libraries, we chose Dojo because we believe that it is heading in the right direction and judging by the support it is getting, so do a lot of other folks. Dojo is an open source project (currently version 3.1) and it seems that the folks working on the project are spending their time working on the features and functionality rather than working on documentation which is the downside of Dojo. The documentation is improving every week but as it stands at the moment, it is pretty weak. Come on guys, make me change this entry. 

 

Hopefully my exploits can help other people. I suppose the easiest way to look at the use of Dojo elements in HTML, is to look at Dojo as CSS on steroids. If you treat it as a fancy CSS tags then we found that it is has a pretty short learning curve. This perspective also makes it easy for the webmasters who know HTML and CSS to understand and use.

 

Widgets are what Dojo calls the CSS-like items that can be used as HTML elements. Basically a Widget is a fully functional item that provides some functionality and is included in the Dojo package. Widgets allow you to include some pretty fancy features without having to write a line of code and, considering my coding capabilities, that is a good thing!!

 

I am assuming that Dojo is installed on the web server and is functioning correctly. The Dojo documentation covers that pretty well. Therefore, for our script, we need to make sure that there is a link to the dojo library. This statement achieves that for us: <script type=”text/javascript” src=”../../dojo.js”></script>

 

Because the tabbed box is a widget and not a native Dojo call, we will also need to find it. Unfortunately the documentation doesn’t make this easy but the great demo and test scripts that are included with Dojo are a great help to understanding things. The tab widget is not a single large widget but a collection of widgets that in total will provide all of tab capability that we desire. Because these statements are JavaScript, we need to include them inside the HTML as per normal JavaScript using script tags. So things would look like this:

<script type=”text/javascript”>

dojo.require(”dojo.widget.TabContainer”);

dojo.require(”dojo.widget.ContentPane”);

</script>

We have included two different widgets here. The names make them pretty self-explanatory. TabContainer is the main tab box widget and the ContentPane is the widget that will provide us with the functionality to display a tab pane with content.

 

Now onto the fun part and actually create something. Let’s create the TabContainer and call it MainTabContainer. Just like CSS, we do not close the DIV tag because we want the tab panes to be children of the TabContainer element. So let’s create two tab panes and give them some content that we want them to display. The four lines of HTML look like this:

<div dojoType=”TabContainer” id=”mainTabContainer” >

<div dojoType=”ContentPane” >Contents of Tab 1 Pane</div>

<div dojoType=”ContentPane” >Contents of Tab 2 Pane</div>

</div>

 

And this is the result:

Screenshot of the result

Pretty nifty considering it only took 3 lines of HTML to create it. The bad news is that it takes up the width of the whole page and we can’t see the content. Out of principle we do all of our HTML formatting via CSS and therefore we are going to add in some CSS here.

 

To stop displaying the TabContainer across the whole page, let’s create a block that we want the tab panes to be displayed in. If you want your tabs to be displayed across the whole page then naturally you do not need this positioning. Here is the CSS code specific for the placement.

 

#tabBlock {

top: 150px;

left: 120px;

width: 320px;

height: 80px;

}

 

And the associated DIV tag in HTML before and after the Dojo Tab lines.

 

<div id=”tabBlock”>

<div id=”mainTabContainer” dojoType=”TabContainer” >

<div dojoType=”ContentPane” >Contents of Tab 1</div>

<div dojoType=”ContentPane” >Contents of Tab 2</div>

</div>

</div>

 

While we are in CSS let’s add some customization to the TabContainer and tell it use 100% of the TabBlock. To do this, we create some CSS formatting structure for the mainTabContainer DIV id. The CSS element tag needs to be the same as the id that we assigned to the TabContainer.

 

#mainTabContainer {

width: 100%;

height: 100%

}

 

 

And now things look like this:

Screenshot

 

Now to label those tabs make the 2nd tab open up instead of the first one. To do this, we add the label parameter to the ContentPane containing whatever we want to be displayed in the tab. To open the 2nd tab by default we need to give id’s to ContentPane’s that we want to refer to and we simply add an id=”name”. Now we tell the TabContainer widget which tab to open with the selectedTab=”tab2″ parameter.  If you have upgraded to dojo 4.0 then you will need to use selectedChild instead of Selected Tab because the use of selectedTab will be totally deprecated in release 5.0.

 

<div id=”tabBlock”>

For dojo 3.1, use the following line:

<div id=”mainTabContainer” dojoType=”TabContainer” selectedTab=”tab2″ >

For dojo 4.0, use the following line:

<div id=”mainTabContainer” dojoType=”TabContainer” selectedChild=”tab2″ >

 <div dojoType=”ContentPane” label=”tab1″ id=”tab1″ >Contents of Tab 1</div>

<div dojoType=”ContentPane” label=”tab2″ id=”tab2″>Contents of Tab 2</div>

</div>

</div>

And now we have the following being displayed:

Screenshot

This is looking a lot better but the text positioning is not quite right because it is too close to the edge of the tab box. Again we turn to CSS for the solution and all it takes is a simple padding instruction. The trick is determining what CSS element to use. It turns out that Dojo uses a class called dojoTabPaneWrapper, so all we have to do is customize this class.

 

.dojoTabPaneWrapper {

padding : 5px;

}

 

So now the output result looks like this:

Screenshot

So here is the full listing:

 

<html xmlns=”http://www.w3.org/1999/xhtml” xml:lang=”en” lang=”en”>

<head>

<title>Tab test page</title>

 

<script type=”text/javascript” src=”./dojo/dojo.js”></script>

<script type=”text/javascript”>

dojo.require(”dojo.widget.TabContainer”);

dojo.require(”dojo.widget.ContentPane”);

</script>

 

<style type=”text/css”>

.dojoTabPaneWrapper {

padding : 5px;

overflow: hidden;

}

 

#tabBlock {

top: 150px;

left: 120px;

width: 320px;

height: 80px;

}

 

#mainTabContainer {

width: 100%;

height: 100%

}

 

</style>

</head>

<body>

<div id=”tabBlock”>

<div id=”mainTabContainer” dojoType=”TabContainer” selectedTab=”tab2″ >

<div dojoType=”ContentPane” label=”tab1″ id=”tab1″>Contents of Tab 1</div>

<div dojoType=”ContentPane” label=”tab2″ id=”tab2″>Contents of Tab 2</div>

</div>

</div>

</body>

</html>

 

Let’s take this to the next step and instead of having all the contents of the boxes in the same html file, let’s link to other files. Now instead of using the ContentPane widget, So the first thing we need to do is add the dojo.require statement. Let’s add this link to the same JavaScript segment that contains the other dojo.require statements:

dojo.require(”dojo.widget.LinkPane”);

 

The HTML statement to add the additional tab pane looks like this:

<a dojoType=”LinkPane” href=”include.inc” refreshOnShow=”true” label=”tab3″ id=”tab3″></a>

 

I used the label parameter to maintain a consistent look with the rest of the statements but the following will display the exact same result:

<a dojoType=”LinkPane” href=”include.inc” refreshOnShow=”true” id=”tab3″>tab3</a>

 

Warning, choose how you want to label your tabs because if you use both, it will display both!

 

The href statement is pointing to an external file and our case the file contains the following statements:

 

<li>line 1

<li>line 2

<li>line 3

<li>line 4

<li>line 5

 

The result is as follows:

Screenshot

I have clicked on the 3rd tab here so that I can see it. The default setting of automatically displaying the 2nd tab still works on the 3rd the widget has added scrollbars. The size of the tabBlock is what is causing this and therefore if I remove the height from the tabBlock CSS definition, it will use the full height of the browser window and look like this.

Screenshot

So the whole code looks like this:

 

<html xmlns=”http://www.w3.org/1999/xhtml” xml:lang=”en” lang=”en”>

<head>

<title>Tab test page</title>

 

<script type=”text/javascript”>

var djConfig = { isDebug: true };

</script>

<script type=”text/javascript” src=”./dojo/dojo.js”></script>

<script type=”text/javascript”>

dojo.require(”dojo.lfx”);

dojo.require(”dojo.dom”);

dojo.require(”dojo.widget.TabContainer”);

dojo.require(”dojo.widget.LinkPane”);

dojo.require(”dojo.widget.ContentPane”);

</script>

 

<style type=”text/css”>

.dojoTabPaneWrapper {

padding : 5px;

}

 

#tabBlock {

top: 150px;

left: 120px;

width: 320px;

}

 

#mainTabContainer {

width: 100%;

height: 100%

}

 

</style>

</head>

 

<body>

<div id=”tabBlock”>

<div id=”mainTabContainer” dojoType=”TabContainer” selectedTab=”tab2″ >

<div dojoType=”ContentPane” label=”tab1″ id=”tab1″>Contents of Tab 1</div>

<div dojoType=”ContentPane” label=”tab2″ id=”tab2″>Contents of Tab 2</div>

<a dojoType=”LinkPane” href=”include.inc” label=”tab3″ id=”tab3″></a>

</div>

</div>

</body>

</html>

 

Full source can be found at: http://www.buzzfizz.com/blog/scripts/dojotabs-html.zip

 

If you are running dojo 4.0, then you will need to edit the files to use the newer calls.