Tabs are an intuitive way for a user to navigate elements on a web page. Using tabs, you can create multi-tab forms, pages of an article, multi-tab navigation links, or other types of pages where there is too much content to fit on one page. Using two ColdFusion custom tags -- one for the tab functionality and one for each individual tab -- you can create a simple way to add tabs to a ColdFusion page. The tab code shown in the article is simple, but can be used to expand on, or you can simply use the techniques shown with your own tab code.

Custom Tags

To use the tutorial, you should be somewhat familiar with custom tags. Custom tags have been covered numerous times at Community MX:

http://communitymx.com/search.cfm?searchbox=coldfusion+custom+tags

Using similar techniques, we'll create two tags: tabs.cfm and tab.cfm. They will both be saved in a directory named "tags" at the site root. You can name the folder anything you want, however. To use the tags on a page, you will use the <cfimport> tag at the top of each page that will use the tab code:

<cfimport taglib="tags">

The "prefix" attribute could be used as well, but if you use a prefix attribute, you have to use it on every tag:

<myprefix:tab>
content
</myprefix:tab>

If you do not use a prefix, you can use the tag without one:

<tab>
content
</tab>

The HTML for the tabs will look like this:

<div id="divTabs">
<a href="javascript:;" onclick="tab(1);" id="tab1" title="Tab 1 ">Tab 1 </a>
<a href="javascript:;" onclick="tab(2);" id="tab2" title="Tab 2 ">Tab 2 </a>
<a href="javascript:;" onclick="tab(3);" id="tab3" title="Tab 3 ">Tab 3 </a>
</div>
<div id="divPages">
<div id="page1"> Stuff here </div>
<div id="page2"> More stuff here </div>
<div id="page3"> Even more stuff </div>
</div>

Basically, the HTML for the tab switchers, along with the JavaScript and CSS references for the code will all be contained within the tabs.cfm page. The tab.cfm page will contain an opening and closing <div> tag for the individual tab, and any relevant code for the tab.

The tab.cfm Page

The code for the tab.cfm page is shown below:

<cfparam name="attributes.tab" default="1" />

<!--- Start of tab --->
<cfif thistag.executionmode eq "start">
<div id="page<cfoutput>#attributes.tab#</cfoutput>">
</cfif>

<!--- End of tabs code --->
<cfif thistag.executionmode eq "end">
</div>
</cfif>

As with all CF custom tags, you can have a start tag or an end tag. In this example, the start tag contains the opening <div> with the attribute "tab", which will be a tab number. The end tag will only contain the closing </div> tag.

The tabs.cfm page

The code for the tabs.cfm page is shown below. The start tag contains the JavaScript and CSS, which will be placed in the document head by using the <cfhtmlhead> tag. The <cfsavecontent> tag simply packs the head content into a variable for manageability. The only attribute for the tag is tabcount, in which you tell the tag how many tabs you are going to have.:

<cfparam name="attributes.tabcount" default="3" />

<!--- Start of tabs code --->
<cfif thistag.executionmode eq "start">
<cfparam name="url.tab" default="1">
<!--- Save the javascript and css to the head--->
<cfsavecontent variable="javascript"><script type="text/javascript">
// Set the current page in a global variable
var currentPage;

function tab(which) {
  var links = document.getElementById('divTabs').getElementsByTagName('a');
  for(var i=1; i <= links.length; i++) {
    links[i-1].className = (i==which) ? 'current' : '';
    eval("document.getElementById('page" + i + "').style.display='" + ((i==which) ? "block" : "none") + "'");
  }
  currentPage = which;
}
</script>

<style type="text/css">
/* TAB stuff */
.show {margin-left: 1.5em;margin-bottom: 1em;padding-left: .5em;border-left: 1px solid #76685D;display: block;}
.hide { display: none;}
#divTabs {margin: 2em 0px -1px 5px;}
#divTabs a{font-weight: bold;text-decoration: none;padding: 3px 5px 2px 5px;border: 1px solid #425929;
background-color: #E7E4E2;color: #000;font-size: 14px; margin-bottom:-2px;}
#divTabs a:hover{background-color:#A1978F;color: #FFF;}
#divTabs a.current{border-bottom: 1px solid #FFF;background-color:#fff;color: #000;}
#divPages{margin: 2px 0px;padding: 20px;border: 1px solid #425929;}
#divPages div {display:none;}
div#page1 {display:block;}
</style>
</cfsavecontent>
<cfhtmlhead text='#javascript#'>

<div id="divTabs">
<!--- Loop through the number of tabs and create one link for each --->
<cfloop from="1" to="#attributes.tabcount#" index="i">
<cfif not IsDefined("attributes.tabtitles")>
<cfset title = "Tab#i#">
<cfelse>
<cfset title = ListGetAt("#attributes.tabtitles#",i)>
</cfif>
<cfoutput><a href="javascript:;" onclick="tab(#i#);" id="tab#i#" title="#title#">#title#</a></cfoutput>
</cfloop>
</div>
<!--- Create a container for all tabs --->
<div id="divPages">
</cfif>

<!--- End of tabs code --->
<cfif thistag.executionmode eq "end">
</div>
</cfif>

Using the Tags

To utilize the tabs and tab custom tags, simply import the tag library with a <cfimport> tag. Then create a container using the <tabs> tag. Inside of this, simply add your <tab> tags:

<cfimport taglib="tags">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Tab Test </title>
</head>
<body onload="tab(1)">
<tabs tabcount="3" tabtitles="Howdy,More,Even more">
  <tab tab="1">Stuff here</tab>
  <tab tab="2">More stuff here</tab>
  <tab tab="3">Even more stuff</tab>
</tabs>
</body>
</html>

Within the individual tabs, you can insert your html content. To create a multipage form, put a form tag around the entire <tabs> section, and use tables or other formatting within the <tab> tags to contain your form fields:

<cfimport taglib="tags">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Untitled Document</title>
</head>
<body onload="tab(1)">
<h1>Fill in the form</h1>
<form name="form1" action="tabform.cfm" method="post">
<tabs tabcount="3" tabtitles="Howdy,More,Even more">
<tab tab="1">

<h2>Page 1</h2>
<table>
<tr>
<td>First Name </td>
<td>
<input type="text" name="textfield" />
</td>
</tr>
<tr>
<td>Middle Name </td>
<td><input type="text" name="textfield2" /></td>
</tr>
<tr>
<td>Last Name </td>
<td><input type="text" name="textfield3" /></td>
</tr>
</table>
<input type="button" value="Next" onclick="tab(2)" />
</tab>
<tab tab="2">

<h2>Page 2</h2>
<table>
<tr>
<td>Address 1 </td>
<td>
<input type="text" name="textfield4" />
</td>
</tr>
<tr>
<td>City</td>
<td><input type="text" name="textfield5" /></td>
</tr>
<tr>
<td>State</td>
<td><input type="text" name="textfield6" /></td>
</tr>
<tr>
<td>Zip</td>
<td><input type="text" name="textfield7" /></td>
</tr>
</table>
<input type="button" value="Next" onclick="tab(3)" />
</tab>
<tab tab="3">

<h2>Page 3</h2>
<table>
<tr>
<td>How did you hear about us? </td>
<td><input type="text" name="textfield8" /></td>
</tr>
<tr>
<td>Email address </td>
<td><input type="text" name="textfield9" /></td>
</tr>
<tr>
<td>Confirm email </td>
<td><input type="text" name="textfield10" /></td>
</tr>
</table>
<input type="submit" name="submit" value="Submit" />
</tab>
</tabs>

</form>
</body>
</html>

Conclusion

With some simple code, you can turn a ColdFusion page into a multi-tab page by using custom tags. This article showed how you might implement a simple tab system, but the technique can also be used with your own tab code.