Click here to Skip to main content
15,860,972 members
Articles / Programming Languages / Javascript
Article

DHTML Hierarchical Web Tab

Rate me:
Please Sign up or sign in to vote.
4.62/5 (41 votes)
23 Sep 20058 min read 197.2K   3.3K   107   36
A client-side dynamic hierarchical web tab with DXImageTransform effects.

Image 1

Introduction

My previous DHTML Web Tab article implemented a simple client-side web tab using HTML, JavaScript and CSS. Using the same methods of configurability and implementation style as the previous web tab, this article extends the web tab by providing a hierarchical system of web tabs with visual DXImageTransform filter effects. That is, each tab can consist of further sub tabs. For UI simplicity, the hierarchy of tabs is limited to one level deep.

Configuration

Parallel to the previous implementation, the tabs and their respective local/remote content sources are specified in an array; each string item in the arrays represent a tab and details of it separated by a “|” pipe character. Note that each string item as well as an array is followed by a “,” comma, except the last. The difference from the previous implementation however, is that the first string element in each array defines the parent tab and the subsequent string elements in that same array define the child tabs. For example, the tabs in the above screenshot were constructed using the following configuration:

JavaScript
var tabs = new Array
(
 new Array("Google|http://www.google.com/", 
   "News|http://news.google.com/", "Froogle|http://froogle.google.com/"),
 new Array("Microsoft|http://www.microsoft.com/|*", 
   "MSDN|http://www.msdn.com/", 
   "Office|http://office.microsoft.com/home/default.aspx"),
 new Array("Yahoo!|http://www.yahoo.com/", 
   "News|http://news.yahoo.com/", 
   "Finance|http://finance.yahoo.com/", 
   "Mail|http://mail.yahoo.com/")
);

In general, every first element in each array defines a parent tab and the subsequent elements as corresponding child tabs. The following template summarizes:

"Parent tab-text | URI | [*]", ["Child1 tab-text | URI"], 
    ["Child2 tab-text | URI"], ["ChildX tab-text | URI"], ...

Square brackets “[…]” denote optional parameters, thus, child tabs are optional. The following screenshot example illustrates how to use the template:

Image 2

A second “|” pipe character followed by a “*” wildcard character after specifying the URI of a parent tab will make that specific parent tab a default selected tab when the page loads, example:

JavaScript
"Google | http://www.google.com/ | *"

Internet Explorer DXImageTransform filter effects can be applied to child tabs via assigning a global variable named DXImageTransformFilter to one of the many DXImageTransform filters. A few examples of DXImageTransform filters included:

JavaScript
DXImageTransform.Microsoft.Wheel(duration=2, spokes=5)
DXImageTransform.Microsoft.Barn(duration=2, orientation=horizontal)
DXImageTransform.Microsoft.Blinds(duration=2, bands=5)
DXImageTransform.Microsoft.CheckerBoard(duration=2)
DXImageTransform.Microsoft.Fade(duration=2)
DXImageTransform.Microsoft.GradientWipe(duration=2, wipeStyle=0)
DXImageTransform.Microsoft.Iris(duration=2, irisStyle=STAR)
DXImageTransform.Microsoft.Iris(duration=2, irisStyle=CIRCLE)
DXImageTransform.Microsoft.Pixelate(duration=2, maxSquare=40)
DXImageTransform.Microsoft.Wheel(duration=2, spokes=5)
DXImageTransform.Microsoft.RandomDissolve(duration=0.5)
DXImageTransform.Microsoft.Spiral(duration=2)
DXImageTransform.Microsoft.Stretch(duration=2, stretchStyle=push)
DXImageTransform.Microsoft.Strips(duration=2, motion=rightdown)

For more on DXImageTransform filter effects and their configuration, see Introduction to Filters and Transitions in MSDN. All of the above listed example DXImageTransform filter effects are stored into an array named DXImageTransformLibrary; thus, a library of filters can be built-up. Assigning the global variable DXImageTransformFilter to null will use a random filter effect from the library of filters. For example:

A visual “fade” effect DXImageTransform filter:

JavaScript
var DXImageTransformFilter = 
  "DXImageTransform.Microsoft.Fade(duration=2)"

Again, the same visual “fade” effect DXImageTransform filter, but specified from the library:

JavaScript
var DXImageTransformFilter = DXImageTransformLibrary[4];

Or, use a random DXImageTransform filter effect:

JavaScript
var DXImageTransformFilter = null;

That completes the configuration of the web tab in script; the final step is to declare HTML <DIV> container objects in the body of the web page as:

HTML
<DIV ID="divTabStrip">
<DIV ID="divTabFrame">

Finally, the web tab is initialized via calling the tabOnLoad function:

<BODY onLoad="tabOnLoad()">

Look & Feel

Borrowing from the previous implementation of the DHTML Web Tab, the look & feel of the tabs are adjusted entirely with CSS. For completeness, the basics are described. When a tab is selected by being clicked upon, its look & feel is defined by the .tabOn style. Conversely, a tab’s neutral look & feel in its unselected state is defined by the .tabOff style. The attributes that are configurable for each .tabOn & .tabOff style are as below, .tabOn style shown in this example:

HTML
FONT-FAMILY: Verdana;
FONT-SIZE: 11;
FONT-WEIGHT: 700;
TEXT-ALIGN: CENTER;
COLOR: #FFFFFF;
BACKGROUND-COLOR: #FF9900;
BORDER-BOTTOM: #FF9900 1PX SOLID;
BORDER-TOP: #FF9900 1PX SOLID;
BORDER-LEFT: #FF9900 1PX SOLID;
BORDER-RIGHT: #000000 1PX SOLID;
HEIGHT: 20;
CURSOR: HAND;

Likewise, the look & feel of the tab frame, which just essentially is an <IFRAME>, is adjusted via the CSS .tabFrame style; attributes configurable are:

HTML
BORDER-RIGHT: #FF9900 9PX SOLID;
BORDER-TOP: #FF9900 9PX SOLID;
SCROLLBAR-FACE-COLOR: #6699CC;
SCROLLBAR-HIGHLIGHT-COLOR: #FFFFFF;
BORDER-LEFT: #FF9900 9PX SOLID; WIDTH: 100%;
SCROLLBAR-SHADOW-COLOR: #6699CC;
SCROLLBAR-ARROW-COLOR: #FFFFFF;
BORDER-BOTTOM: #FF9900 9PX SOLID;
SCROLLBAR-DARKSHADOW-COLOR: #6699CC;
HEIGHT: 95%;

A point worthy of reiteration from the previous article is that the BORDER-TOP color style attribute of the <IFRAME> main tab content area, .tabFrame, has to be the same as the BORDER-BOTTOM color style attribute of the tab buttons when they are selected, .tabOn. This is so that when the tab button is selected, it will look as part of the <IFRAME> and provide a continuous and consistent look.

Design

Just as the previous implementation, this web tab is again composed of HTML buttons for the tabs and an <IFRAME> for the main content area. However, in addition to this implementation, every child set of tabs reside in an individual table division:

Image 3

The first table division is where all the parent tabs reside. A parent tab can consist of zero or more child tabs. Each of those child set of tabs belong to a subsequent unique table division.

All child sets (table divisions which house the sub tabs) are by default hidden from view. Aside the main operation of populating the <IFRAME> with content upon clicking a parent tab, the unique table division which houses the corresponding sub tabs in the tab hierarchy appear visually with a DXImageTransform filter effect.

Since only one table division (child set of sub tabs) is visible at a time, in theory, this should eliminate any potential horizontal scrolling that may be caused by a tab strip consisting of a large number of tabs/sub tabs.

Implementation

The hierarchy of tabs are managed by using an array of arrays; - each item in the array is an array itself. This is purely so to simplify the construction of the web tab – rather than looping through one user-defined array at a time, a nested loop can be implemented to loop through nested arrays; thus referencing only one user-defined array.

The web tab is constructed when the tabOnLoad function is called, it’s the “main” entry point of the web tab construction. This declares a HTML table, but before the table is completed, calls are made to the tabLoadParents() and tabLoadChildren() functions:

JavaScript
HTML += "<TABLE BORDER='0' CELLPADDING='0' CELLSPACING='0' WIDTH='100%'>";
HTML += "<TD ALIGN='LEFT'>";
tabLoadParents();
tabLoadChildren();

The tabLoadParents() function seeks out the parent tabs by looping through each array, picking out the first string element in each. Every first string element in each array is then split at every “|” pipe character to extract various parts of the string, creating a HTML button with the .tabOff CSS style as well as assigning the buttons with a unique ID and an onClick event handled by the tabOnClick function:

JavaScript
for (var i = 1; i < tabs.length; i++)
{
 var tab = tabs[i][0].split("|");
 HTML += "<INPUT TYPE='BUTTON' ID="+ i + 
         " CLASS='tabOff' VALUE="+tab[0] + 
         " onClick='tabOnClick("+i+", "+i+", 0)'>";
}

Every HTML button created in the tabLoadParents() function is added to a table division which in turn is appended to the HTML table created earlier.

Next, the tabOnLoad function calls the tabLoadChildren() function. The tabLoadChildren() function first establishes what DXImageTransform filter effect has been selected to be used on child tabs when they appear. If no filter has been selected, then a random filter is applied from the DXImageTransformLibrary:

JavaScript
if (DXImageTransformFilter == null)
{
 DXImageTransform = DXImageTransformLibrary[Math.round
                      ((Math.random()*DXImageTransformLibrary.length-1)+0)];
}

The tabLoadChildren() function then performs its main task of seeking out child sets of sub tabs from the array of arrays via a nested for-loop. Since every first element in each array defines a parent tab, the subsequent elements define the parent tab’s corresponding child tabs; thus, the nested for-loop begins at the second position of each array and loops until the last element in each array is reached.

JavaScript
for (var i = 1; i < tabs.length; i++)
{
 HTML += "<TD STYLE="+DXImageTransform+" ID=child"+i+">";

 for (var j = 1; j < tabs[i].length; j++)
 {
  var tab = tabs[i][j].split("|"); 

  var childID = i + "" + j;
  HTML += "<INPUT TYPE='BUTTON' ID="+ childID + 
          " CLASS='tabOff' VALUE="+tab[0] + 
          " onClick='tabOnClick("+childID+", "+i+", "+j+")'> ";  
 }

 HTML += "</TD>;
}

Every string element representing a child tab is given the same treatment of being split at every “|” pipe character to extract various parts of the string, creating a HTML button with the .tabOff style as well as assigning them with a unique ID and an onClick event handled by the tabOnClick function. After the nested for-loop has completed an iteration, that is, seeked out a child set of tabs, then that child set is allocated its own table division which is then appended to the HTML table created earlier. Every table division is also allocated a unique ID representing a child set of tabs.

After making calls to the tabLoadParents() and tabLoadChildren() functions to construct the respective parent and child tabs, the tabOnLoad() function then completes the HTML table constructed earlier and binds it to the divTabStrip <DIV> container object:

JavaScript
divTabStrip.innerHTML = HTML;

The tabOnClick function is called when any tab, either parent or child is clicked. The purpose of this function is to change the style of the clicked tab to the .tabOn style and change all other tabs to the .tabOff style as well as updating the <IFRAME> content area. The function requires three parameters; ID, parent and child. The first parameter represents the ID of which tab (HTML button) has been clicked – either parent or child so that the .tabOn CSS class can be applied to it. The last two parameters pinpoint the exact location of the clicked tab in the nested arrays so that further information can be sought-out about that tab to update the contents of the <IFRAME>:

JavaScript
var tab = tabs[parent][child].split("|");
divTabFrame.innerHTML = "<IFRAME SRC="+tab[1]+" CLASS='tabFrame'></IFRAME>";

If the tabOnClick function is called by a tab with the last parameter child set to 0, it signifies that the caller is a parent tab which has been clicked and therefore instructs all child sets of sub tabs (table divisions) to disappear except the corresponding child set of sub tabs that belong to the clicked parent tab:

JavaScript
if (child == 0)
{
 for (var i = 1; i < tabs.length; i++)
 {
  tabHide("child"+i);
 }

 tabShow("child"+ID);
}

The tabShow and tabHide functions respectively show and hide table divisions which house sets of child tabs. The functions are called with a parameter defining the ID of which table division to show or hide. A call to each of these functions apply the selected DXImageTransform filter to the table division in question, using:

JavaScript
var e = document.getElementById(ID);
e.filters[0].Apply();

When a call is made to show a particular table division to show a set of child tabs, the table division is made visible playing the DXImageTransform filter effect, using:

JavaScript
e.style.display = "block";
e.filters[0].Play();

Likewise, if a call is made to hide a particular table division to hide a set of child tabs, the table division is made invisible and the DXImageTransform filter effect stopped:

JavaScript
e.style.display = "none";
e.filters[0].Stop();

Notes

  • As a quick bug/logical error fix, an empty nested array is required to be declared before any other tab hierarchy arrays are defined:
    JavaScript
    var tabs = new Array
    (
     /*BUGFIX*/ new Array(),
     new Array("Google|http://www.google.com/|*",
         "News|http://news.google.com/",
         "Froogle|http://froogle.google.com/"),
     new Array(…)
    );
    
  • Extended from DHTML Web Tab Control.
  • Tested only with IE6.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionHow to make this cross browser compliant Pin
Member 108691077-Jul-14 7:31
Member 108691077-Jul-14 7:31 
QuestionReally a nice artical ! Pin
parasaniasandip10-Jun-13 21:20
parasaniasandip10-Jun-13 21:20 
QuestionSave Cotent in tabs Pin
embo128-Oct-07 16:26
embo128-Oct-07 16:26 
Generaleasy question! Pin
roninzyf18-Sep-07 23:03
roninzyf18-Sep-07 23:03 
hi,i like it. but i have a easy question!I want to chang the link-page for myself.
example:
new Array("Google|http://www.google.com/", "News|http://news.google.com/", "Froogle|http://froogle.google.com/"),
changed:
new Array("Google|default.asp")
but the result was wrong!
Can you tell me how to do?
thank you!
GeneralRe: easy question! Pin
Steve Puri18-Sep-07 23:50
Steve Puri18-Sep-07 23:50 
GeneralSTOP RELOADING Pin
Delver7-Jun-06 8:36
Delver7-Jun-06 8:36 
QuestionUsing this with C#? Pin
RK KL1-May-06 13:07
RK KL1-May-06 13:07 
Generalchange colors of scrollbar of .aspx page(asp.net) Pin
Member 239449315-Oct-05 0:04
Member 239449315-Oct-05 0:04 
QuestionIFrame background color? Pin
gogetsome13-Oct-05 8:23
gogetsome13-Oct-05 8:23 
GeneralParent - child visual reference Pin
16-Jul-05 13:14
suss16-Jul-05 13:14 
GeneralHide or Show tabs based on user roles Pin
coriolanx16-Jun-04 6:17
coriolanx16-Jun-04 6:17 
GeneralRe: Hide or Show tabs based on user roles Pin
Anonymous28-Jun-04 6:54
Anonymous28-Jun-04 6:54 
GeneralRe: Hide or Show tabs based on user roles Pin
Anonymous28-Jun-04 7:20
Anonymous28-Jun-04 7:20 
GeneralIFRAME Background Color Pin
Anonymous18-May-04 10:40
Anonymous18-May-04 10:40 
Generalpassing variables between frames in your given example Pin
Member 95039712-May-04 0:05
Member 95039712-May-04 0:05 
GeneralPersistent iFrames Pin
dmoses9-Feb-04 5:26
dmoses9-Feb-04 5:26 
GeneralRe: Persistent iFrames Pin
Steve Puri9-Feb-04 7:38
Steve Puri9-Feb-04 7:38 
GeneralRe: Persistent iFrames Pin
dmoses9-Feb-04 9:43
dmoses9-Feb-04 9:43 
Generalonly IE - not good Pin
Winfried Heitmann8-Feb-04 23:04
Winfried Heitmann8-Feb-04 23:04 
GeneralRe: only IE - not good Pin
Steve Puri9-Feb-04 6:42
Steve Puri9-Feb-04 6:42 
GeneralRe: only IE - not good Pin
Phillip Temple8-Apr-04 23:04
sussPhillip Temple8-Apr-04 23:04 
GeneralRe: only IE - not good Pin
DevKM14-Jan-07 23:38
DevKM14-Jan-07 23:38 
GeneralRe: only IE - not good Pin
wopper28-Sep-05 5:49
wopper28-Sep-05 5:49 
Generalscrollbar color Pin
Fiend15-Feb-04 9:37
Fiend15-Feb-04 9:37 
GeneralRe: scrollbar color Pin
Steve Puri6-Feb-04 3:27
Steve Puri6-Feb-04 3:27 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.