Click here to Skip to main content
Click here to Skip to main content
Go to top

DHTML Hierarchical Web Tab

, 23 Sep 2005
Rate this:
Please Sign up or sign in to vote.
A client-side dynamic hierarchical web tab with DXImageTransform effects.

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:

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:

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:

"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:

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:

var DXImageTransformFilter = 
  “DXImageTransform.Microsoft.Fade(duration=2)”

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

var DXImageTransformFilter = DXImageTransformLibrary[4];

Or, use a random DXImageTransform filter effect:

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:

<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:

 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:

 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:

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:

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:

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:

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.

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:

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>:

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:

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:

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:

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:

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:
     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

Share

About the Author

Steve Puri

United Kingdom United Kingdom
No Biography provided

Comments and Discussions

 
QuestionHow to make this cross browser compliant PinmemberMember 108691077-Jul-14 7:31 
QuestionReally a nice artical ! Pinmemberparasaniasandip10-Jun-13 21:20 
QuestionSave Cotent in tabs Pinmemberembo128-Oct-07 16:26 
Generaleasy question! Pinmemberroninzyf18-Sep-07 23:03 
GeneralRe: easy question! PinmemberSteve Puri18-Sep-07 23:50 
GeneralSTOP RELOADING PinmemberDelver7-Jun-06 8:36 
QuestionUsing this with C#? PinmemberHyperX1-May-06 13:07 
Generalchange colors of scrollbar of .aspx page(asp.net) Pinsussfalgun modi15-Oct-05 0:04 
QuestionIFrame background color? Pinmembergogetsome13-Oct-05 8:23 
GeneralParent - child visual reference Pinmemberjohn de sousa16-Jul-05 13:14 
GeneralHide or Show tabs based on user roles Pinmembercoriolanx16-Jun-04 6:17 
GeneralRe: Hide or Show tabs based on user roles PinsussAnonymous28-Jun-04 6:54 
GeneralRe: Hide or Show tabs based on user roles PinsussAnonymous28-Jun-04 7:20 
GeneralIFRAME Background Color PinsussAnonymous18-May-04 10:40 
Generalpassing variables between frames in your given example Pinmemberkishor kumar12-May-04 0:05 
GeneralPersistent iFrames Pinmemberdmoses9-Feb-04 5:26 
GeneralRe: Persistent iFrames PinmemberSteve Puri9-Feb-04 7:38 
GeneralRe: Persistent iFrames Pinmemberdmoses9-Feb-04 9:43 
Generalonly IE - not good PinmemberWinfried Heitmann8-Feb-04 23:04 
GeneralRe: only IE - not good PinmemberSteve Puri9-Feb-04 6:42 
GeneralRe: only IE - not good PinsussPhillip Temple8-Apr-04 23:04 
GeneralRe: only IE - not good PinmemberDevKM14-Jan-07 23:38 
GeneralRe: only IE - not good Pinmemberwopper28-Sep-05 5:49 
Generalscrollbar color PinmemberFiend15-Feb-04 9:37 
GeneralRe: scrollbar color PinmemberSteve Puri6-Feb-04 3:27 
GeneralTables are dead, long live CSS!!! PinmemberRui Dias Lopes2-Feb-04 10:23 
GeneralRandom filter issue/bug PinmemberSteve Puri29-Jan-04 9:09 
GeneralRespect PinmemberMitch2829-Jan-04 2:04 
GeneralUsing It With Network HTML Files PinmemberBassam Abdul-Baki29-Jan-04 1:54 
GeneralRe: Using It With Network HTML Files PinmemberBassam Abdul-Baki29-Jan-04 2:01 
GeneralRe: Using It With Network HTML Files PinmemberBassam Abdul-Baki29-Jan-04 2:29 
GeneralRe: Using It With Network HTML Files PinmemberSteve Puri29-Jan-04 8:52 
GeneralRe: Using It With Network HTML Files PinmemberBassam Abdul-Baki29-Jan-04 9:58 
GeneralRe: Using It With Network HTML Files Pinmembercarlito punk30-Jan-04 21:49 
GeneralRe: Using It With Network HTML Files PinmemberSteve Puri31-Jan-04 2:06 
GeneralExcellent PinmemberPavlos Touboulidis28-Jan-04 1:16 

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

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

| Advertise | Privacy | Mobile
Web03 | 2.8.140926.1 | Last Updated 23 Sep 2005
Article Copyright 2004 by Steve Puri
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid