Although this script is not very polished, and could probably use some enhancements to increase flexibility and make the script unobtrusive; I have implemented this simple tab navigation script in some projects for back-ends that manage applications. By combining some simple functionality available by using the Prototype and Script.aculo.us javascript libraries, it is pretty simple to create an interactive tab navigation scheme.
The CSS is fairly straightforward and allows you to modify the color scheme of the tabs, add rounded corners to the tabs, and anything else you can think of:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
| <style>
#tabs{
margin-left: 4px;
padding: 0;
background: transparent;
voice-family: ""}"";
voice-family: inherit;
padding-left: 5px;
}
#tabs ul{
font: bold 11px Arial, Verdana, sans-serif;
margin:0;
padding:0;
list-style:none;
}
#tabs li{
display:inline;
margin:0 2px 0 0;
padding:0;
text-transform:uppercase;
}
#tabs a{
float:left;
background:#A3BBE6 url(images/tabs_left.gif) no-repeat left top;
margin:0 2px 0 0;
padding:0 0 1px 3px;
text-decoration:none;
}
#tabs a span{
float:left;
display:block;
background: transparent url(images/tabs_right.gif) no-repeat right top;
padding:4px 9px 2px 6px;
}
#tabs a span{float:none;}
#tabs a:hover{background-color: #7E94B9;color: white;}
#tabs a:hover span{background-color: #7E94B9;}
#tabHeaderActive span, #tabHeaderActive a { background-color: #42577B; color:#fff;}
.tabContent {
clear:both;
border:2px solid #42577B;
padding-top:2px;
background-color:#FFF;
}
</style> |
The HTML is also very simple, which I often generate using server-side scripting to create the layout based on an XML or database schema. For each tab in your layout, there is both a tabHeader and a corresponding tabContent div:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
| <div id="tabs">
<ul>
<li style="margin-left: 1px" id="tabHeader1" class="currenttab"><a href="javascript:void(0)" onClick="toggleTab(1,6)"><span>Tab 1</span></a></li>
<li id="tabHeader2"><a href="javascript:void(0)" onClick="toggleTab(2,6)" ><span>Tab 2</span></a></li>
<li id="tabHeader3"><a href="javascript:void(0)" onclick="toggleTab(3,6)"><span>Tab 3</span></a></li>
<li id="tabHeader4"><a href="javascript:void(0)" onClick="toggleTab(4,6)"><span>Tab 4</span></a></li>
<li id="tabHeader5"><a href="javascript:void(0)" onclick="toggleTab(5,6);"><span>Tab 5</span></a></li>
<li id="tabHeader6"><a href="javascript:void(0)" onclick="toggleTab(6,6);"><span>Tab 6</span></a></li>
</ul>
</div>
<div id="tabscontent">
<div id="tabContent1" class="tabContent" style="display:none;">
<br /><div>First Tab Content goes here</div>
</div>
<div id="tabContent2" class="tabContent" style="display:none;">
<br /><div>Second Tab Content goes here</div>
</div>
<div id="tabContent3" class="tabContent" style="display:none;">
<br /><div>Third Tab Content goes here</div>
</div>
<div id="tabContent4" class="tabContent" style="display:none;">
<br /><div>Fourth Tab Content goes here</div>
</div>
<div id="tabContent5" class="tabContent" style="display:none;">
<br /><div>Fifth Tab Content goes here</div>
</div>
<div id="tabContent6" class="tabContent" style="display:none;">
<br /><div>Sixth Tab Content goes here</div>
</div>
</div><!--End of tabscontent-->
</div><!--End of tabs--> |
This is where we get into the JavaScript. First, be sure that you include the Prototype and Script.aculo.us javascript libraries.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
| /*-----------------------------------------------------------
Toggles element's display value
Input: any number of element id's
Output: none
---------------------------------------------------------*/
function toggleDisp() {
for (var i=0;i<arguments.length;i++){
var d = $(arguments[i]);
if (d.style.display == 'none')
d.style.display = 'block';
else
d.style.display = 'none';
}
}
/*-----------------------------------------------------------
Toggles tabs - Closes any open tabs, and then opens current tab
Input: 1.The number of the current tab
2.The number of tabs
3.(optional)The number of the tab to leave open
4.(optional)Pass in true or false whether or not to animate the open/close of the tabs
Output: none
---------------------------------------------------------*/
function toggleTab(num,numelems,opennum,animate) {
if ($('tabContent'+num).style.display == 'none'){
for (var i=1;i<=numelems;i++){
if ((opennum == null) || (opennum != i)){
var temph = 'tabHeader'+i;
var h = $(temph);
if (!h){
var h = $('tabHeaderActive');
h.id = temph;
}
var tempc = 'tabContent'+i;
var c = $(tempc);
if(c.style.display != 'none'){
if (animate || typeof animate == 'undefined')
Effect.toggle(tempc,'blind',{duration:0.5, queue:{scope:'menus', limit: 3}});
else
toggleDisp(tempc);
}
}
}
var h = $('tabHeader'+num);
if (h)
h.id = 'tabHeaderActive';
h.blur();
var c = $('tabContent'+num);
c.style.marginTop = '2px';
if (animate || typeof animate == 'undefined'){
Effect.toggle('tabContent'+num,'blind',{duration:0.5, queue:{scope:'menus', position:'end', limit: 3}});
}else{
toggleDisp('tabContent'+num);
}
}
} |
The first function, toggleDisp, is a simple function in which you can pass multiple element ids or the element object and switches the display mode of the element from ‘block’ to ‘none’ and vice-versa. This can also be implemented using the Effect.Toggle function in the script.aculo.us library if you wish. The second function, toggleTab, does all the work of actually opening and closing the tabs. The function has 3 arguments. First, the total number of tabs - this is where I could add some additional logic to automatically get the tab elements and count them, thus not requiring this argument. Second, the "number" of the tab to leave open - I implemented this functionality to allow nested tabs. Below is an example of where I wanted to have nested tabs:

As you can see, I have 4 main tabs across the top, and I also have a nested tab in this particular instance. Since I want to be able to open and close the ‘Add Administrator’ tab within the ‘Manage Grant Administrators’ tab, I have to pass in the tab number of the ‘Manage Grant Administrators’ tab to that when a user clicks on the ‘Add Administrator’ tab, the tab it is nested within is not closed - make sense? As a side note: this entire management tool is completely AJAXified and contained on a single page, making it incredible easy and fast to manage the Grant application I developed.
Lastly, the third argument to the toggleDisp function is a boolean value to specify if you want the opening and closing of the tabs to be animated or not. This was added to allow for ability to turn off the scroll up/down animation of the tab contents when it is not desired, and is specified for each tab.
Here is an example of the Script.aculo.us interactive tab navigation I have discussed. I have also shared this code on the Script.aculo.us wiki site, in the hope that others will find value in this simple script, and perhaps make modifications and enhancements to further expand the simplicity and effectiveness it offers. Please let me know if you use this script and find it helpful.
Update:
Read about HistoryTabs.js
Read More