Javascript And CSS Tutorial - Dynamic Tabbed Panels
|
|
| Tab Name: | Tab Contents: |
| The above is a working example using the code in this tutorial. You can add tabs and panel content by typing them in the corresponding textboxes. Each time the 'Add Tab' button is clicked, a new tab will be added to the control with your content. I placed a limit of 6 tabs on this example, but in reality, you could have an unlimited number of tabs. The names are limited to 6 characters so they do not overflow the width of the tab. In practice, you'd probably want to implement auto ellipsing so long tab names are automatically truncated. |
The rest of this tutorial will guide you through the process of creating tab controls similar to the one shown in the above example.
The HTML
We'll start by creating a div that just holds our tabs and panels. My style sheet sets the width of this div to 500 pixels, but that value can be changed to fit your needs.
<div class="tabControl"></div>
Now we need a table that will hold the tabs. The tabs will be stored in a row inside this table called "mainTabArea". The one empty cell already placed in this row is used to fill the rest of the row not currently occupied by tabs. The height of "mainTabArea" controls how tall your tabs will be. For this example, I set them to 20 pixels. The "return false" in the onselectstart event prevents the tab's text from being selected. This is especially important since most browsers will select an element's text when a user double clicks. The tabHolder CSS class also contains a Mozilla specific style for preventing text selection: "-moz-user-select:none".
<div class="tabControl">
<table class="tabHolder" cellspacing="0" cellpadding="0"
onselectstart="return false;">
<tr id="mainTabArea">
<td style="font-size:1px;"> </td>
</tr>
</table>
</div>
<table class="tabHolder" cellspacing="0" cellpadding="0"
onselectstart="return false;">
<tr id="mainTabArea">
<td style="font-size:1px;"> </td>
</tr>
</table>
</div>
The next thing we need to do is create a div named "mainPanelArea" to hold the contents of each tab panel. This div is located directly underneath the table holding our tabs and controls how tall your panels will be. For this example, I set the height to 50 pixels.
<div class="tabControl">
<table class="tabHolder" cellspacing="0" cellpadding="0"
onselectstart="return false;">
<tr id="mainTabArea">
<td style="font-size:1px;"> </td>
</tr>
</table>
<div id="mainPanelArea" class="tabPanel">
</div>
</div>
<table class="tabHolder" cellspacing="0" cellpadding="0"
onselectstart="return false;">
<tr id="mainTabArea">
<td style="font-size:1px;"> </td>
</tr>
</table>
<div id="mainPanelArea" class="tabPanel">
</div>
</div>
That's all the HTML needed to create the above tabbed panel example. Of course, this is not the only possible set up for the tabs and the panels. The important thing is to have a table row in which we can insert new tabs, and a div into which we can insert the panels.
The CSS
Below is the style sheet used to create the above example. You can modify any of these values to create your desired tab panel.
.tabControl
{
width:500px; /* tab control width */
}
.lowTab, .highTab
{
background-repeat:no-repeat;
cursor:pointer;
width:75px; /* tab width */
}
.lowTab
{
background-image:url('files/tab_inactive_75x20.gif');
}
.highTab
{
background-image:url('files/tab_active_75x20.gif');
}
.tabHolder
{
width:100%;
height:20px; /* tab height */
border-collapse:collapse;
border-spacing:0px;
-moz-user-select:none; /* removes text selection */
}
.tabPanel
{
top:20px; /* should equal tab height */
left:0px;
width:100%;
height:50px; /* tab panel height */
background-color:#cad7e3;
border:1px solid #3c597b;
}
{
width:500px; /* tab control width */
}
.lowTab, .highTab
{
background-repeat:no-repeat;
cursor:pointer;
width:75px; /* tab width */
}
.lowTab
{
background-image:url('files/tab_inactive_75x20.gif');
}
.highTab
{
background-image:url('files/tab_active_75x20.gif');
}
.tabHolder
{
width:100%;
height:20px; /* tab height */
border-collapse:collapse;
border-spacing:0px;
-moz-user-select:none; /* removes text selection */
}
.tabPanel
{
top:20px; /* should equal tab height */
left:0px;
width:100%;
height:50px; /* tab panel height */
background-color:#cad7e3;
border:1px solid #3c597b;
}
The Javascript
Now for the javascript code. We are going to define a javascript class, so that you can have multiple tab panels on a single page (you would just need to instantiate the object multiple times - one for each tabbed panel). First off, the declaration:
function TabbedPanel(controllerName, tabElement, panelElement)
You might wonder 'why is he declaring a function?'. Well, in javascript, the word function is also used to declare classes. You will see more of how this works as we see more of the code. Here, the object takes a unique sting as a name ("controllerName"), the html element for holding the tabs ("mainTabArea"), and the html element for holding the panels ("mainPanelArea").
Now for some fields:
function TabbedPanel(controllerName, tabElement, panelElement)
{
//Tabbed Panel Name
this.Name = controllerName;
//ID of next tab
this.tabNumber = 0;
//Current visible panel
this.currentHighPanel = null;
//Current raised tab
this.currentHighTab = null;
//The panel holder element
this.panelContainer = panelElement;
//The tab holder element
this.tabContainer = tabElement;
//CSS style for non-selected tabs
this.lowTabStyle = 'lowTab';
//CSS style for selected tabs
this.highTabStyle = 'highTab';
}
{
//Tabbed Panel Name
this.Name = controllerName;
//ID of next tab
this.tabNumber = 0;
//Current visible panel
this.currentHighPanel = null;
//Current raised tab
this.currentHighTab = null;
//The panel holder element
this.panelContainer = panelElement;
//The tab holder element
this.tabContainer = tabElement;
//CSS style for non-selected tabs
this.lowTabStyle = 'lowTab';
//CSS style for selected tabs
this.highTabStyle = 'highTab';
}
Here we are setting a couple of fields to the values passed in, as well as initializing some others. The comments should do a pretty good job explaining what the fields are. All of these fields are public, so they can be modified after the object has been instantiated - such as the css style names.
Now for a long one - let's add a function to the TabbedPanel class called CreateTab. This function takes a string that will be the displayed name of the new tab.
this.CreateTab = function(tabName)
{
var tabID = this.Name + 'Tab' + this.tabNumber;
var panelID = this.Name + 'Panel' + this.tabNumber;
var panel = document.createElement('div');
panel.style.left = '0px';
panel.style.top = '0px';
panel.style.width = '100%';
panel.style.height = '100%';
panel.style.display = 'none';
panel.tabNum = this.tabNumber;
panel.id = panelID;
if(this.panelContainer.insertAdjacentElement == null)
this.panelContainer.appendChild(panel)
else
this.panelContainer.insertAdjacentElement("beforeEnd",
panel); //Internet Explorer
var cell = this.tabContainer.insertCell(
this.tabContainer.cells.length - 1);
cell.id = tabID;
cell.className = this.lowTabStyle;
cell.tabNum = this.tabNumber;
cell.onclick = this.OnTabClicked;
cell.innerHTML = tabName;
cell.panelObj = this;
this.TabClickEl(cell);
this.tabNumber++;
return panel;
}
{
var tabID = this.Name + 'Tab' + this.tabNumber;
var panelID = this.Name + 'Panel' + this.tabNumber;
var panel = document.createElement('div');
panel.style.left = '0px';
panel.style.top = '0px';
panel.style.width = '100%';
panel.style.height = '100%';
panel.style.display = 'none';
panel.tabNum = this.tabNumber;
panel.id = panelID;
if(this.panelContainer.insertAdjacentElement == null)
this.panelContainer.appendChild(panel)
else
this.panelContainer.insertAdjacentElement("beforeEnd",
panel); //Internet Explorer
var cell = this.tabContainer.insertCell(
this.tabContainer.cells.length - 1);
cell.id = tabID;
cell.className = this.lowTabStyle;
cell.tabNum = this.tabNumber;
cell.onclick = this.OnTabClicked;
cell.innerHTML = tabName;
cell.panelObj = this;
this.TabClickEl(cell);
this.tabNumber++;
return panel;
}
And now for the explanation in English. Let's break this function up and see what each piece does.
First off, we create the ids for the new tab and panel. We want to make sure that they are ids that we can recreate later, so that we can use getElementById - but we also need to make them unique. So we concatenate the tabbed panel name, the word 'Tab' (or 'Panel' if this is the panel id), and a number (which is what is unique to this tab/panel combination).
var tabID = this.Name + 'Tab' + this.tabNumber;
var panelID = this.Name + 'Panel' + this.tabNumber;
var panelID = this.Name + 'Panel' + this.tabNumber;
Next, we create the panel div. Usually, people just append to the innerHTML of an element to add new html to a page, but in this case we actually need a reference to the created element. So instead, we use the function 'createElement' - which does exactly what the name says. The functions returns the new div element, and in the next few lines we set all of the needed properties. Depending on what you might want to use tabbed panels for, you might want to change or add to those properties.
var panel = document.createElement('div');
panel.style.left = '0px';
panel.style.top = '0px';
panel.style.width = '100%';
panel.style.height = '100%';
panel.style.display = 'none';
panel.tabNum = this.tabNumber;
panel.id = panelID;
panel.style.left = '0px';
panel.style.top = '0px';
panel.style.width = '100%';
panel.style.height = '100%';
panel.style.display = 'none';
panel.tabNum = this.tabNumber;
panel.id = panelID;
Once the panel has been created, we insert it into the DOM. Here we use one method for IE, and a second (standard) method for everybody else (IE, of course, does not implement the standard method).
if(this.panelContainer.insertAdjacentElement == null)
this.panelContainer.appendChild(panel)
else
this.panelContainer.insertAdjacentElement(
"beforeEnd", panel); //Internet Explorer
this.panelContainer.appendChild(panel)
else
this.panelContainer.insertAdjacentElement(
"beforeEnd", panel); //Internet Explorer
Next, we create the tab cell for this panel. Here, we use a method available on table rows - insertCell. This takes the position to insert the cell at (in this case we are passing it before the end filler cell described in the HTML section - potentially you could insert it wherever you wanted to) and returns the newly created cell. Again we set a number of the properties of the cell - including the onClick method (which we have not yet defined), the contents of the cell (here the string passed in when CreateTab was called), and a reference to the current object (used later on in the onClick method). After all the properties have been defined, we call the method TabClickEl - which we have not yet defined. It will do the work of raising the given tab cell and its associated panel - because here we assume that the newly created tab/panel should be the visible one.
var cell = this.tabContainer.insertCell(
this.tabContainer.cells.length - 1);
cell.id = tabID;
cell.className = this.lowTabStyle;
cell.tabNum = this.tabNumber;
cell.onclick = this.OnTabClicked;
cell.innerHTML = tabName;
cell.panelObj = this;
this.TabClickEl(cell);
this.tabContainer.cells.length - 1);
cell.id = tabID;
cell.className = this.lowTabStyle;
cell.tabNum = this.tabNumber;
cell.onclick = this.OnTabClicked;
cell.innerHTML = tabName;
cell.panelObj = this;
this.TabClickEl(cell);
The final work that this method does is increment the tabNumber field (so the next new tab has a unique number) and then return the new panel (so that the caller can fill the new panel with whatever is supposed to go there).
this.tabNumber++;
return panel;
return panel;
Another major method in the object is TabClickEl (which is short for TabClickElement, because the argument the function takes is a tab cell element). This function, as mentioned above, does the raising and lowering of tabs and panels.
this.TabClickEl = function (element)
{
if(this.currentHighTab == element)
return;
if(this.currentHighTab != null)
this.currentHighTab.className = this.lowTabStyle;
if(this.currentHighPanel != null)
this.currentHighPanel.style.display = 'none';
this.currentHighPanel = null;
this.currentHighTab = null;
if(element == null)
return;
this.currentHighPanel = document.getElementById(
this.Name + 'Panel' + element.tabNum);
if(this.currentHighPanel == null)
return;
this.currentHighTab = element;
this.currentHighTab.className = this.highTabStyle;
this.currentHighPanel.style.display = '';
}
{
if(this.currentHighTab == element)
return;
if(this.currentHighTab != null)
this.currentHighTab.className = this.lowTabStyle;
if(this.currentHighPanel != null)
this.currentHighPanel.style.display = 'none';
this.currentHighPanel = null;
this.currentHighTab = null;
if(element == null)
return;
this.currentHighPanel = document.getElementById(
this.Name + 'Panel' + element.tabNum);
if(this.currentHighPanel == null)
return;
this.currentHighTab = element;
this.currentHighTab.className = this.highTabStyle;
this.currentHighPanel.style.display = '';
}
The first if statement does a very simple check - if the tab you are trying to raise is already raised, don't do anything. Otherwise, if there is a currently raised tab, lower it, and if there is a currently visible panel, hide it. Now, if the tab cell passed in is null, don't raise anything. Next try and get the panel associated with the passed in tab - by recreating the panel id, and using getElementById. If the panel doesn't exist, don't raise anything and return. If the panel does exist, set the current high fields to the newly raised tab and panel, set the tab style to the style for raised tabs, and make the panel visible. Nothing particularly surprising here.
Now that we can create and select tabs, lets take a look at how we can close them. Getting rid of the tab and its associated panel is actually pretty simple - the slightly annoying thing is if the tab that is disappearing is the currently selected tab. If it is, then we need to figure out what tab should now become selected.
this.TabCloseEl = function(element)
{
if(element == null)
return;
if(element == this.currentHighTab)
{
var i = -1;
if(this.tabContainer.cells.length> 2)
{
i = element.cellIndex;
if(i == this.tabContainer.cells.length-2)
i--;
else
i++;
}
if(i>= 0)
this.TabClickEl(this.tabContainer.cells[i]);
else
this.TabClickEl(null);
}
var panel = document.getElementById(this.Name
+ 'Panel' + element.tabNum);
if(panel != null)
this.panelContainer.removeChild(panel);
this.tabContainer.deleteCell(element.cellIndex);
}
{
if(element == null)
return;
if(element == this.currentHighTab)
{
var i = -1;
if(this.tabContainer.cells.length> 2)
{
i = element.cellIndex;
if(i == this.tabContainer.cells.length-2)
i--;
else
i++;
}
if(i>= 0)
this.TabClickEl(this.tabContainer.cells[i]);
else
this.TabClickEl(null);
}
var panel = document.getElementById(this.Name
+ 'Panel' + element.tabNum);
if(panel != null)
this.panelContainer.removeChild(panel);
this.tabContainer.deleteCell(element.cellIndex);
}
The function expects to be handed a tab cell element to deal with (which is why it is called TabCloseEl). First off, if that element is null, then there isn't anything to close, so we return. Next we check to see if the tab being closed is the currently selected tab - and if it is, drop into code to determine what tab will now be selected.
First we create a variable to store the index of the tab that will get selected, and set it to -1 (the 'nothing will get selected' number). Then we check to see if the tab being removed is the last tab left on the tabbed panel (because if it is, there won't be a new tab to select). The way we do this is by checking how many cells are currently contained by the tabContainer - and if it is 2 or less, this is the only cell left. The reason it is 2 or less (not 1 or less) is again because of the filler cell. If there are other cells that can be selected, we set the to-be-selected index variable to the index of the to-be-deleted cell and check to see if it is the right-most cell. If it is we decrement the index, otherwise we increment it. This is because the usual behavior for tabs is to select the tab to the right when the current tab is removed, but if the selected tab is the right-most tab, there is nothing to the right to select - so instead we select the tab to the left.
Now that we have an index, we check to see if it is greater than 0 (i.e., not the -1 'nothing will get selected' value), and if it is, we call TabClickEl on the cell to be selected (which we get by pulling it out of tabContainer using the index). If the index was still -1, we call TabClickEl on 'null' - which causes the current tab to be deslected, but nothing new to be selected.
Now that that is all out of the way, we can actually get around to deleting the tab. We get the panel associated with the tab by recreating the panel's id, do a quick check to make sure it actually exists (because, hey, you never know), and then remove it from the panel container. And finally, we delete the cell from the tab container using the cell index.
One more function to define in this object, and that is the onclick method that is attached to each of the tab cells. It is pretty short, because all it does in the end is call TabClickEl.
this.OnTabClicked = function(event)
{
// Internet Explorer : Other
var el = (event.target == null) ?
window.event.srcElement : event.target;
el.panelObj.TabClickEl(el);
}
{
// Internet Explorer : Other
var el = (event.target == null) ?
window.event.srcElement : event.target;
el.panelObj.TabClickEl(el);
}
Here, we first get the target that caused the call of this function (i.e., the tab cell). It is not exactly clean, thanks to IE, which does not follow the standard for getting event targets. Once we have the tab cell, we call TabClickEl on that tab cell. You might wonder why the code doesn't look like:
this.TabClickEl(el);
Well, I wish it did, but unfortunately that does not work. I don't exactly know why, but when the function is called through an event, 'this' is undefined - it seems the event does not know what instance of the class the function was attached to. So instead, we use a workaround. Back in the tab cell creation, we attached a reference to the object to the cell. So here, we use that reference to call the correct TabClickEl function.
And heres what all the javascript code looks like together:
function TabbedPanel(controllerName, tabElement, panelElement)
{
this.Name = controllerName;
this.tabNumber = 0;
this.currentHighPanel = null;
this.currentHighTab = null;
this.panelContainer = panelElement;
this.tabContainer = tabElement;
this.lowTabStyle = 'lowTab';
this.highTabStyle = 'highTab';
this.CreateTab = function(tabName)
{
var tabID = this.Name + 'Tab' + this.tabNumber;
var panelID = this.Name + 'Panel' + this.tabNumber;
var panel = document.createElement('div');
panel.style.left = '0px';
panel.style.top = '0px';
panel.style.width = '100%';
panel.style.height = '100%';
panel.style.display = 'none';
panel.tabNum = this.tabNumber;
panel.id = panelID;
if(this.panelContainer.insertAdjacentElement == null)
this.panelContainer.appendChild(panel)
else
this.panelContainer.insertAdjacentElement(
"beforeEnd",panel); //Internet Explorer
var cell = this.tabContainer.insertCell(
this.tabContainer.cells.length);
cell.id = tabID;
cell.className = this.lowTabStyle;
cell.tabNum = this.tabNumber;
cell.onclick = this.OnTabClicked;
cell.innerHTML = tabName;
cell.panelObj = this;
this.TabClickEl(cell);
this.tabNumber++;
return panel;
}
this.OnTabClicked = function(event)
{
// Internet Explorer : Other
var el = (event.target == null) ?
window.event.srcElement : event.target;
el.panelObj.TabClickEl(el);
}
this.TabClickEl = function (element)
{
if(this.currentHighTab == element)
return;
if(this.currentHighTab != null)
this.currentHighTab.className = this.lowTabStyle;
if(this.currentHighPanel != null)
this.currentHighPanel.style.display = 'none';
this.currentHighPanel = null;
this.currentHighTab = null;
if(element == null)
return;
this.currentHighPanel = document.getElementById(
this.Name + 'Panel' + element.tabNum);
if(this.currentHighPanel == null)
return;
this.currentHighTab = element;
this.currentHighTab.className = this.highTabStyle;
this.currentHighPanel.style.display = '';
}
this.TabCloseEl = function(element)
{
if(element == null)
return;
if(element == this.currentHighTab)
{
var i = -1;
if(this.tabContainer.cells.length> 2)
{
i = element.cellIndex;
if(i == this.tabContainer.cells.length-2)
i = this.tabContainer.cells.length-3;
else
i++;
}
if(i>= 0)
this.TabClickEl(this.tabContainer.cells[i]);
else
this.TabClickEl(null);
}
var panel = document.getElementById(this.Name
+ 'Panel' + element.tabNum);
if(panel != null)
this.panelContainer.removeChild(panel);
this.tabContainer.deleteCell(element.cellIndex);
}
}
{
this.Name = controllerName;
this.tabNumber = 0;
this.currentHighPanel = null;
this.currentHighTab = null;
this.panelContainer = panelElement;
this.tabContainer = tabElement;
this.lowTabStyle = 'lowTab';
this.highTabStyle = 'highTab';
this.CreateTab = function(tabName)
{
var tabID = this.Name + 'Tab' + this.tabNumber;
var panelID = this.Name + 'Panel' + this.tabNumber;
var panel = document.createElement('div');
panel.style.left = '0px';
panel.style.top = '0px';
panel.style.width = '100%';
panel.style.height = '100%';
panel.style.display = 'none';
panel.tabNum = this.tabNumber;
panel.id = panelID;
if(this.panelContainer.insertAdjacentElement == null)
this.panelContainer.appendChild(panel)
else
this.panelContainer.insertAdjacentElement(
"beforeEnd",panel); //Internet Explorer
var cell = this.tabContainer.insertCell(
this.tabContainer.cells.length);
cell.id = tabID;
cell.className = this.lowTabStyle;
cell.tabNum = this.tabNumber;
cell.onclick = this.OnTabClicked;
cell.innerHTML = tabName;
cell.panelObj = this;
this.TabClickEl(cell);
this.tabNumber++;
return panel;
}
this.OnTabClicked = function(event)
{
// Internet Explorer : Other
var el = (event.target == null) ?
window.event.srcElement : event.target;
el.panelObj.TabClickEl(el);
}
this.TabClickEl = function (element)
{
if(this.currentHighTab == element)
return;
if(this.currentHighTab != null)
this.currentHighTab.className = this.lowTabStyle;
if(this.currentHighPanel != null)
this.currentHighPanel.style.display = 'none';
this.currentHighPanel = null;
this.currentHighTab = null;
if(element == null)
return;
this.currentHighPanel = document.getElementById(
this.Name + 'Panel' + element.tabNum);
if(this.currentHighPanel == null)
return;
this.currentHighTab = element;
this.currentHighTab.className = this.highTabStyle;
this.currentHighPanel.style.display = '';
}
this.TabCloseEl = function(element)
{
if(element == null)
return;
if(element == this.currentHighTab)
{
var i = -1;
if(this.tabContainer.cells.length> 2)
{
i = element.cellIndex;
if(i == this.tabContainer.cells.length-2)
i = this.tabContainer.cells.length-3;
else
i++;
}
if(i>= 0)
this.TabClickEl(this.tabContainer.cells[i]);
else
this.TabClickEl(null);
}
var panel = document.getElementById(this.Name
+ 'Panel' + element.tabNum);
if(panel != null)
this.panelContainer.removeChild(panel);
this.tabContainer.deleteCell(element.cellIndex);
}
}
Putting It All Together
So how do we use the TabbedPanel object to dynamically create tabs? Once the above code is implemented, creating tabs is a very simple process. Let's start with the HTML created at the beginning of this tutorial.
<div class="tabControl">
<table class="tabHolder" cellspacing="0" cellpadding="0"
onselectstart="return false;">
<tr id="mainTabArea">
<td style="font-size:1px;"> </td>
</tr>
</table>
<div id="mainPanelArea" class="tabPanel">
</div>
</div>
<table class="tabHolder" cellspacing="0" cellpadding="0"
onselectstart="return false;">
<tr id="mainTabArea">
<td style="font-size:1px;"> </td>
</tr>
</table>
<div id="mainPanelArea" class="tabPanel">
</div>
</div>
The only thing left to do is create an instance of the TabbedPanel class and start creating tabs.
//create the TabbedPanel object
var tabController =
new TabbedPanel('tabControllerId',
document.getElementById('mainTabArea'),
document.getElementById('mainPanelArea'));
//create a tab named 'Example'
var newTabPanel = tabController.CreateTab('Example');
//fill the contents of the new tab's panel
newTabPanel.innerHTML = 'The example tab\'s contents';
//close the currently selected tab
tabController.CloseTabEl(tabController.currentHighTab);
var tabController =
new TabbedPanel('tabControllerId',
document.getElementById('mainTabArea'),
document.getElementById('mainPanelArea'));
//create a tab named 'Example'
var newTabPanel = tabController.CreateTab('Example');
//fill the contents of the new tab's panel
newTabPanel.innerHTML = 'The example tab\'s contents';
//close the currently selected tab
tabController.CloseTabEl(tabController.currentHighTab);
This should give you a jumping off point to do whatever you want to do with tabbed panels. If you'd like to see these tabs in action, Gaming Textures uses tab controls very similar to those created in this tutorial.
You can download the style sheet here, and the Javascript file here that were used for this tutorial.
Posted in CSS, Javascript, All Tutorials by The Tallest |

July 31st, 2007 at 9:25 am
thanks for the code. i was working all night to get this things done. finally i got this.
thanks!
November 19th, 2007 at 3:45 am
Hi,
This is indeed a great job..
Would have been more happy if you had given a sample code for download (along the js and css file).
Regards,
December 20th, 2007 at 8:34 am
Its wonderful but i cann’t download the code(java script) and css from the ‘here’ option
December 20th, 2007 at 11:03 am
Its wonderful, this has been fixed you should now be able to obtain the code from those links.
January 3rd, 2008 at 11:00 am
hello im new to css and designing..
pls help on creating css for selected tab panels content,
i already have the css for selected tab but i don’t know how to create the css for the selected contents..
example:
content1, content2, content3
when user selects content one it should change its color..different from the other,..
any help is appreciated..
thanks
January 14th, 2008 at 8:05 am
This looks very good, I am planning to play with code to implement my changes…
May 9th, 2008 at 6:49 am
I reallly like your tabbed panels. Really very nice.
May 12th, 2008 at 8:42 am
Thanks, this looks useful and the source is very clean.
June 29th, 2008 at 11:43 am
Hi, thank, i was looking for this exmaple for thousands of hrs…haha
finally you did it…..
July 8th, 2008 at 7:20 am
hi, This is Gajender singh, new in web design and this will really help me a lot
Thanks buddy
July 23rd, 2008 at 4:59 am
It’s cool.
Thanks you.