<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html> <head> <title>Tab Pane (WebFX)</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <!-- webfxlayout.js --> <script type="text/javascript"> /* this is a dummy webfxlayout file to be used in download zip files */
/* Do includes */
if (window.pathToRoot == null) pathToRoot = "./";
document.write('<link type="text/css" rel="stylesheet" href="local/webfxlayout.css">'); webfxMenuDefaultImagePath = pathToRoot + "images/";
/* end includes */
/* set up browser checks and add a simple emulation for IE4 */
// check browsers var op = /opera 5|opera/5/i.test(navigator.userAgent); var ie = !op && /msie/i.test(navigator.userAgent); // preventing opera to be identified as ie var mz = !op && /mozilla/5/i.test(navigator.userAgent); // preventing opera to be identified as mz
if (ie && document.getElementById == null) { // ie4 document.getElementById = function(sId) { return document.all[sId]; }; }
/* end browser checks */
webfxLayout = { writeTitle : function (s, s2) { document.write("<div id='webfx-title-background'></div>"); if (op) { document.write("<h1 id='webfx-title' style='top:9px;'>" + s + "</h1>"); } else { document.write("<h1 id='webfx-title'>" + s + "</h1>"); }
if (s2 == null) s2 = "WebFX - What you never thought possible!"; if (op) { document.write("<span id='webfx-sub-title' style='top:46px;'>" + s2 + "</span>"); } else { document.write("<span id='webfx-sub-title'>" + s2 + "</span>"); } }, writeMainTitle : function () { this.writeTitle("WebFX", "What you never thought possible!"); }, writeTopMenuBar : function () { document.write("<div id='webfx-menu-bar-1'></div>"); if (op) { document.write("<style>.webfx-menu-bar a {padding-top:3px;}</style>"); document.write("<div id='webfx-menu-bar-2' style='height:2px;'></div>"); } else document.write("<div id='webfx-menu-bar-2'></div>"); document.write("<div id='webfx-menu-bar'>");// div is closed in writeBottomMenuBar }, writeBottomMenuBar : function () { document.write("</div>"); if (op) document.write("<div id='webfx-menu-bar-3' style='height:0px;'></div>"); else document.write("<div id='webfx-menu-bar-3'></div>"); document.write("<div id='webfx-menu-bar-4'></div>"); document.write("<div id='webfx-menu-bar-5'></div>"); }, writeMenu : function () { this.writeTopMenuBar(); //document.write(webfxMenuBar); this.writeBottomMenuBar(); }, writeDesignedByEdger : function () { if (ie && document.body.currentStyle.writingMode != null) document.write("<div id='webfx-about'>Page designed and maintained by " + "<a href='mailto:erik@eae.net'>Erik Arvidsson</a> & " + "<a href='mailto:eae@eae.net'>Emil A Eklund</a>.</div>"); } };
if (ie && window.attachEvent) { window.attachEvent("onload", function () { var scrollBorderColor = "rgb(120,172,255)"; var scrollFaceColor = "rgb(234,242,255)"; with (document.body.style) { scrollbarDarkShadowColor = scrollBorderColor; scrollbar3dLightColor = scrollBorderColor; scrollbarArrowColor = "black"; scrollbarBaseColor = scrollFaceColor; scrollbarFaceColor = scrollFaceColor; scrollbarHighlightColor = scrollFaceColor; scrollbarShadowColor = scrollFaceColor; scrollbarTrackColor = "white"; } }); }
/* we also need some dummy constructors */ webfxMenuBar = { add : function () {} }; function WebFXMenu() { this.add = function () {}; } function WebFXMenuItem() {} function WebFXMenuSeparator() {} function WebFXMenuButton() {} </script> <!-- webfxapi.js --> <script type="text/javascript"> /* * This script is used for WebFX Api pages * * It defines one funtion and includes helptip.js, helptip.css and webfxapi.css */
document.write( "<script type='text/javascript' src='local/helptip.js'></script>" ); document.write( "<link type='text/css' rel='stylesheet' href='local/helptip.css' />" ); document.write( "<link type='text/css' rel='stylesheet' href='local/webfxapi.css' />" );
function toggleMethodArguments( e, a ) { if ( a && a.nextSibling && typeof a.nextSibling.innerHTML != "undefined" && typeof showHelpTip != "undefined" ) { showHelpTip( e, a.nextSibling.innerHTML ); } } </script> <!-- tabpane.js --> <script type="text/javascript"> /*---------------------------------------------------------------------------- | Tab Pane 1.02 | |-----------------------------------------------------------------------------| | Created by Erik Arvidsson | | (http://webfx.eae.net/contact.html#erik) | | For WebFX (http://webfx.eae.net/) | |-----------------------------------------------------------------------------| | Copyright (c) 1998 - 2003 Erik Arvidsson | |-----------------------------------------------------------------------------| | This software is provided "as is", without warranty of any kind, express or | | implied, including but not limited to the warranties of merchantability, | | fitness for a particular purpose and noninfringement. In no event shall the | | authors or copyright holders be liable for any claim, damages or other | | liability, whether in an action of contract, tort or otherwise, arising | | from, out of or in connection with the software or the use or other | | dealings in the software. | | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | This software is available under the three different licenses mentioned | | below. To use this software you must chose, and qualify, for one of those. | | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | The WebFX Non-Commercial License http://webfx.eae.net/license.html | | Permits anyone the right to use the software in a non-commercial context | | free of charge. | | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | The WebFX Commercial license http://webfx.eae.net/commercial.html | | Permits the license holder the right to use the software in a commercial | | context. Such license must be specifically obtained, however it's valid for | | any number of implementations of the licensed software. | | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | GPL - The GNU General Public License http://www.gnu.org/licenses/gpl.txt | | Permits anyone the right to use and modify the software without limitations | | as long as proper credits are given and the original and modified source | | code are included. Requires that the final product, software derivate from | | the original source or any software utilizing a GPL component, such as | | this, is also licensed under the GPL license. | |-----------------------------------------------------------------------------| | 2002-01-?? | First working version | | 2002-02-17 | Cleaned up for 1.0 public version | | 2003-02-18 | Changed from javascript uri for anchors to return false | | 2003-03-03 | Added dispose methods to release IE memory | |-----------------------------------------------------------------------------| | Dependencies: *.css a css file to define the layout | |-----------------------------------------------------------------------------| | Created 2002-01-?? | All changes are in the log above. | Updated 2003-03-03 | ----------------------------------------------------------------------------*/
// This function is used to define if the browser supports the needed // features function hasSupport() {
if (typeof hasSupport.support != "undefined") return hasSupport.support; var ie55 = /msie 5.[56789]/i.test( navigator.userAgent ); hasSupport.support = ( typeof document.implementation != "undefined" && document.implementation.hasFeature( "html", "1.0" ) || ie55 ) // IE55 has a serious DOM1 bug... Patch it! if ( ie55 ) { document._getElementsByTagName = document.getElementsByTagName; document.getElementsByTagName = function ( sTagName ) { if ( sTagName == "*" ) return document.all; else return document._getElementsByTagName( sTagName ); }; }
return hasSupport.support; }
/////////////////////////////////////////////////////////////////////////////////// // The constructor for tab panes // // el : HTMLElement The html element used to represent the tab pane // bUseCookie : Boolean Optional. Default is true. Used to determine whether to us // persistance using cookies or not // function WebFXTabPane( el, bUseCookie ) { if ( !hasSupport() || el == null ) return; this.element = el; this.element.tabPane = this; this.pages = []; this.selectedIndex = null; this.useCookie = bUseCookie != null ? bUseCookie : true; // add class name tag to class name this.element.className = this.classNameTag + " " + this.element.className; // add tab row this.tabRow = document.createElement( "div" ); this.tabRow.className = "tab-row"; el.insertBefore( this.tabRow, el.firstChild );
var tabIndex = 0; if ( this.useCookie ) { tabIndex = Number( WebFXTabPane.getCookie( "webfxtab_" + this.element.id ) ); if ( isNaN( tabIndex ) ) tabIndex = 0; } this.selectedIndex = tabIndex; // loop through child nodes and add them var cs = el.childNodes; var n; for (var i = 0; i < cs.length; i++) { if (cs[i].nodeType == 1 && cs[i].className == "tab-page") { this.addTabPage( cs[i] ); } } }
WebFXTabPane.prototype.classNameTag = "dynamic-tab-pane-control";
WebFXTabPane.prototype.setSelectedIndex = function ( n ) { if (this.selectedIndex != n) { if (this.selectedIndex != null && this.pages[ this.selectedIndex ] != null ) this.pages[ this.selectedIndex ].hide(); this.selectedIndex = n; this.pages[ this.selectedIndex ].show(); if ( this.useCookie ) WebFXTabPane.setCookie( "webfxtab_" + this.element.id, n ); // session cookie } }; WebFXTabPane.prototype.getSelectedIndex = function () { return this.selectedIndex; }; WebFXTabPane.prototype.addTabPage = function ( oElement ) { if ( !hasSupport() ) return; if ( oElement.tabPage == this ) // already added return oElement.tabPage;
var n = this.pages.length; var tp = this.pages[n] = new WebFXTabPage( oElement, this, n ); tp.tabPane = this; // move the tab out of the box this.tabRow.appendChild( tp.tab ); if ( n == this.selectedIndex ) tp.show(); else tp.hide(); return tp; }; WebFXTabPane.prototype.dispose = function () { this.element.tabPane = null; this.element = null; this.tabRow = null; for (var i = 0; i < this.pages.length; i++) { this.pages[i].dispose(); this.pages[i] = null; } this.pages = null; };
// Cookie handling WebFXTabPane.setCookie = function ( sName, sValue, nDays ) { var expires = ""; if ( nDays ) { var d = new Date(); d.setTime( d.getTime() + nDays * 24 * 60 * 60 * 1000 ); expires = "; expires=" + d.toGMTString(); }
document.cookie = sName + "=" + sValue + expires + "; path=/"; };
WebFXTabPane.getCookie = function (sName) { var re = new RegExp( "(;|^)[^;]*(" + sName + ")=([^;]*)(;|$)" ); var res = re.exec( document.cookie ); return res != null ? res[3] : null; };
WebFXTabPane.removeCookie = function ( name ) { setCookie( name, "", -1 ); };
/////////////////////////////////////////////////////////////////////////////////// // The constructor for tab pages. This one should not be used. // Use WebFXTabPage.addTabPage instead // // el : HTMLElement The html element used to represent the tab pane // tabPane : WebFXTabPane The parent tab pane // nindex : Number The index of the page in the parent pane page array // function WebFXTabPage( el, tabPane, nIndex ) { if ( !hasSupport() || el == null ) return; this.element = el; this.element.tabPage = this; this.index = nIndex; var cs = el.childNodes; for (var i = 0; i < cs.length; i++) { if (cs[i].nodeType == 1 && cs[i].className == "tab") { this.tab = cs[i]; break; } } // insert a tag around content to support keyboard navigation var a = document.createElement( "A" ); this.aElement = a; a.href = "#"; a.onclick = function () { return false; }; while ( this.tab.hasChildNodes() ) a.appendChild( this.tab.firstChild ); this.tab.appendChild( a );
// hook up events, using DOM0 var oThis = this; this.tab.onclick = function () { oThis.select(); }; this.tab.onmouseover = function () { WebFXTabPage.tabOver( oThis ); }; this.tab.onmouseout = function () { WebFXTabPage.tabOut( oThis ); }; }
WebFXTabPage.prototype.show = function () { var el = this.tab; var s = el.className + " selected"; s = s.replace(/ +/g, " "); el.className = s; this.element.style.display = "block"; };
WebFXTabPage.prototype.hide = function () { var el = this.tab; var s = el.className; s = s.replace(/ selected/g, ""); el.className = s;
this.element.style.display = "none"; }; WebFXTabPage.prototype.select = function () { this.tabPane.setSelectedIndex( this.index ); }; WebFXTabPage.prototype.dispose = function () { this.aElement.onclick = null; this.aElement = null; this.element.tabPage = null; this.tab.onclick = null; this.tab.onmouseover = null; this.tab.onmouseout = null; this.tab = null; this.tabPane = null; this.element = null; };
WebFXTabPage.tabOver = function ( tabpage ) { var el = tabpage.tab; var s = el.className + " hover"; s = s.replace(/ +/g, " "); el.className = s; };
WebFXTabPage.tabOut = function ( tabpage ) { var el = tabpage.tab; var s = el.className; s = s.replace(/ hover/g, ""); el.className = s; };
// This function initializes all uninitialized tab panes and tab pages function setupAllTabs() { if ( !hasSupport() ) return;
var all = document.getElementsByTagName( "*" ); var l = all.length; var tabPaneRe = /tab-pane/; var tabPageRe = /tab-page/; var cn, el; var parentTabPane; for ( var i = 0; i < l; i++ ) { el = all[i] cn = el.className;
// no className if ( cn == "" ) continue; // uninitiated tab pane if ( tabPaneRe.test( cn ) && !el.tabPane ) new WebFXTabPane( el ); // unitiated tab page wit a valid tab pane parent else if ( tabPageRe.test( cn ) && !el.tabPage && tabPaneRe.test( el.parentNode.className ) ) { el.parentNode.tabPane.addTabPage( el ); } } }
function disposeAllTabs() { if ( !hasSupport() ) return; var all = document.getElementsByTagName( "*" ); var l = all.length; var tabPaneRe = /tab-pane/; var cn, el; var tabPanes = []; for ( var i = 0; i < l; i++ ) { el = all[i] cn = el.className;
// no className if ( cn == "" ) continue; // tab pane if ( tabPaneRe.test( cn ) && el.tabPane ) tabPanes[tabPanes.length] = el.tabPane; } for (var i = tabPanes.length - 1; i >= 0; i--) { tabPanes[i].dispose(); tabPanes[i] = null; } }
// initialization hook up
// DOM2 if ( typeof window.addEventListener != "undefined" ) window.addEventListener( "load", setupAllTabs, false );
// IE else if ( typeof window.attachEvent != "undefined" ) { window.attachEvent( "onload", setupAllTabs ); window.attachEvent( "onunload", disposeAllTabs ); }
else { if ( window.onload != null ) { var oldOnload = window.onload; window.onload = function ( e ) { oldOnload( e ); setupAllTabs(); }; } else window.onload = setupAllTabs; } </script> <!-- tab.webfx.css --> <style type="text/css" rel="StyleSheet"> /*
bright: rgb(234,242,255); normal: rgb(120,172,255); dark: rgb(0,66,174);
*/
.dynamic-tab-pane-control.tab-pane { position: relative; width: 100%; }
.dynamic-tab-pane-control .tab-row .tab { font-family: Verdana, Helvetica, Arial; font-size: 12px; cursor: Default; display: inline; margin: 1px -5px 1px 5px; float: left; padding: 3px 6px 3px 6px; background: rgb(234,242,255); border: 1px solid; border-color: rgb(120,172,255); border-left: 0; border-bottom: 0; border-top: 0; cursor: hand; cursor: pointer; z-index: 1; position: relative; top: 0; }
.dynamic-tab-pane-control .tab-row .tab.selected { border: 1px solid rgb(120,172,255); border-bottom: 0; z-index: 3; padding: 2px 6px 5px 6px; margin: 1px -6px -2px 0px; top: -2px; background: white; }
.dynamic-tab-pane-control .tab-row .tab a { font-family: Verdana, Helvetica, Arial; font-size: 13px; color: rgb(0,66,174); text-decoration: none; cursor: hand; cursor: pointer; }
.dynamic-tab-pane-control .tab-row .hover a { color: rgb(0,66,174); }
.dynamic-tab-pane-control .tab-row .tab.selected a { font-weight: bold; }
.dynamic-tab-pane-control .tab-page { clear: both; border: 1px solid rgb(120,172,255); background: White; z-index: 2; position: relative; top: -2px; color: Black; font-family: Verdana, Helvetica, Arial; font-size: 13px; padding: 10px; }
.dynamic-tab-pane-control .tab-row { z-index: 1; white-space: nowrap; background: rgb(234,242,255); height: 1.85em; width: 100%; }
</style> <style type="text/css">
.dynamic-tab-pane-control .tab-page { height: 500px; width: 558px; overflow: auto; }
.dynamic-tab-pane-control .tab-page .dynamic-tab-pane-control .tab-page { height: 100px; }
form { margin: 0; padding: 0; }
/* over ride styles from webfxlayout */
.dynamic-tab-pane-control.tab-pane { margin: 10px; width: 580px; }
.dynamic-tab-pane-control h2 { text-align: center; width: auto; }
.dynamic-tab-pane-control h2 a { display: inline; width: auto; }
.dynamic-tab-pane-control a:hover { background: transparent; }
.dynamic-tab-pane-control .tab-page h2 { text-align: left; }
</style>
<script type="text/javascript">
var tabPane;
function showArticleTab( sName ) { if (typeof tabPane != "undefined" ) { switch ( sName ) { case "main": tabPane.setSelectedIndex( 0 ); break; case "usage": tabPane.setSelectedIndex( 1 ); break; case "api": tabPane.setSelectedIndex( 2 ); break;
case "implementation": tabPane.setSelectedIndex( 3 ); break; case "looknfeel": tabPane.setSelectedIndex( 4 ); break; } } }
// help tips htDom = "Document Object Model 1 is a standard developed by the W3C.<br />" + "<a href="http://www.w3.org/DOM/" target="_blank">http://www.w3.org/DOM/</a>";
</script>
</head> <body> <!-- WebFX Layout Include --> <script type="text/javascript">
var articleMenu= new WebFXMenu; articleMenu.left = 384; articleMenu.top = 86; articleMenu.width = 140; articleMenu.add(new WebFXMenuItem("Tab Pane", "javascript:showArticleTab( "main" )")); articleMenu.add(new WebFXMenuItem("Usage", "javascript:showArticleTab( "usage" )")); articleMenu.add(new WebFXMenuItem("API", "javascript:showArticleTab( "api" )")); articleMenu.add(new WebFXMenuItem("Implementation", "javascript:showArticleTab( "implementation" )")); articleMenu.add(new WebFXMenuItem("Look & Feel", "javascript:showArticleTab( "looknfeel" )")); articleMenu.add(new WebFXMenuItem("Demo", "demo.html")); articleMenu.add(new WebFXMenuSeparator); articleMenu.add(new WebFXMenuItem("Download", "http://webfx.eae.net/download/tabpane102.zip")); webfxMenuBar.add(new WebFXMenuButton("Article Menu", null, null, articleMenu));
webfxLayout.writeTitle("Tab Pane"); webfxLayout.writeMenu(); webfxLayout.writeDesignedByEdger();
</script> <div class="webfx-main-body"> <!-- end WebFX Layout Includes -->
<!-- begin tab pane --> <div class="tab-pane" id="article-tab">
<script type="text/javascript"> tabPane = new WebFXTabPane( document.getElementById( "article-tab" ), true ); </script>
<!-- begin intro page --> <div class="tab-page" id="intro-page"> <h2 class="tab">Introduction</h2> <script type="text/javascript"> tabPane.addTabPage( document.getElementById( "intro-page" ) ); </script> <p>You might remember.</p>
<p>This Tab Pane control is.</p>
<p>The Tab Pane.</p>
</div> <!-- end intro page -->
<!-- begin usage page --> <div class="tab-page" id="usage-page"> <h2 class="tab">Usage</h2> <script type="text/javascript"> tabPane.addTabPage( document.getElementById( "usage-page" ) ); </script>
<h3>Include the Files</h3>
<p>To.</p>
<h3>The</h3> <p>The.</p>
<p>Below is the code for a simple tab pane with the tab pages.</p>
<pre> <div class="tab-pane" id="tab-pane-1">
<div class="tab-page"> <h2 class="tab">General</h2> This is text of tab 1. This is text of tab 1. This is text of tab 1. This is text of tab 1. </div>
<div class="tab-page"> <h2 class="tab">Privacy</h2> This is text of tab 2. This is text of tab 2. This is text of tab 2. This is text of tab 2. </div> </div> </pre>
<p>Notice that the <code>id</code> is not needed unless two or more tab panes are present in the same document and you are using the persistence feature. </p>
<h3>Initialization</h3>
<p>The best way to.</p>
</div> <!-- end usage tab -->
<!-- begin api tab --> <div class="tab-page" id="api-page"> <h2 class="tab">API</h2> <script type="text/javascript"> tabPane.addTabPage( document.getElementById( "api-page" ) ); </script>
<!-- Generated using api.xsl version 20020217 -->
<!-- Start main output --> <h2>WebFXTabPane</h2> <p>This is the </p> <h3>Syntax</h3> <p><code>
new WebFXTabPane(<span class="methodArgument">oElement</span> [, <span class="methodArgument">bUseCookie</span>])</code></p> <h3>Parameters</h3> <table> <thead> <tr> <td>Name</td> <td>Type</td> <td>Descripton</td> </tr> </thead> <tbody> <tr> <td><code>oElement</code></td> <td><code>HTMLElement</code></td> <td>The html element that represents the tab pane</td> </tr> <tr> <td><code>bUseCookie</code></td> <td><code>Boolean</code></td> <td> <span class="optional">Optional.</span> If this is set to true then the selected tab is persisted. <span class="defaultSentence"> The default value is <code>true</code>. </span> </td> </tr> </tbody> </table> <h3>Static Methods</h3> <table> <thead> <tr> <td>Name</td> <td>Description</td> </tr> </thead> <tbody> <tr> <td> <a class="helpLink" href="javascript://" onclick="toggleMethodArguments( event, this ); return false;">setCookie</a><div class="methodContainer"> <div class="methodInfo"> <h4>Syntax</h4> <p><code><span class="object">object</span>.setCookie(<span class="methodArgument">sName</span>, <span class="methodArgument">sValue</span> [, <span class="methodArgument">nDays</span>])</code></p> <h4>Arguments</h4> <table> <thead> <tr> <td>Name</td> <td>Type</td> <td>Descripton</td> </tr> </thead> <tbody> <tr> <td><code>sName</code></td> <td><code>String</code></td> <td>The name of the cookie</td> </tr> <tr> <td><code>sValue</code></td> <td><code>String</code></td> <td>The value of the cookie</td> </tr> <tr> <td><code>nDays</code></td> <td><code>Number</code></td> <td> <span class="optional">Optional.</span> The number of days to store the cookie </td> </tr> </tbody> </table> <h4>Return Type</h4> <p><code>void</code></p> </div></div> </td> <td>Sets a cookie</td> </tr> <tr> <td> <a class="helpLink" href="javascript://" onclick="toggleMethodArguments( event, this ); return false;">getCookie</a><div class="methodContainer"> <div class="methodInfo"> <h4>Syntax</h4> <p><code><span class="object">object</span>.getCookie(<span class="methodArgument">sName</span>)</code></p> <h4>Arguments</h4> <table> <thead> <tr> <td>Name</td> <td>Type</td> <td>Descripton</td> </tr> </thead> <tbody> <tr> <td><code>sName</code></td> <td><code>String</code></td> <td>The name of the cookie</td> </tr> </tbody> </table> <h4>Return Type</h4> <p><code>String</code></p> </div></div> </td> <td>Retrieves a cookie by name</td> </tr> <tr> <td> <a class="helpLink" href="javascript://" onclick="toggleMethodArguments( event, this ); return false;">removeCookie</a><div class="methodContainer"> <div class="methodInfo"> <h4>Syntax</h4> <p><code><span class="object">object</span>.removeCookie(<span class="methodArgument">sName</span>)</code></p> <h4>Arguments</h4> <table> <thead> <tr> <td>Name</td> <td>Type</td> <td>Descripton</td> </tr> </thead> <tbody> <tr> <td><code>sName</code></td> <td><code>String</code></td> <td>The name of the cookie to remove</td> </tr> </tbody> </table> <h4>Return Type</h4> <p><code>void</code></p> </div></div> </td> <td>Removes a cookie by name</td> </tr> </tbody> </table> <h3>Static Fields</h3> <table> <thead> <tr> <td>Name</td> <td>Type</td> <td>Descripton</td> </tr> </thead> <tbody> <tr> <td colspan="3">None.</td> </tr> </tbody> </table> <h3>Methods</h3> <table> <thead> <tr> <td>Name</td> <td>Description</td> </tr> </thead> <tbody> <tr> <td> <a class="helpLink" href="javascript://" onclick="toggleMethodArguments( event, this ); return false;">addTabPage</a><div class="methodContainer"> <div class="methodInfo"> <h4>Syntax</h4> <p><code><span class="object">object</span>.addTabPage(<span class="methodArgument">oElement</span>)</code></p> <h4>Arguments</h4> <table> <thead> <tr> <td>Name</td> <td>Type</td> <td>Descripton</td> </tr> </thead> <tbody> <tr> <td><code>oElement</code></td> <td><code>HTMLElement</code></td> <td>The html element that represents the tab page</td> </tr> </tbody> </table> <h4>Return Type</h4> <p><code>WebFXTabPage</code></p> </div></div> </td> <td>Adds a tab page by passing an html element</td> </tr> <tr> <td> <a class="helpLink" href="javascript://" onclick="toggleMethodArguments( event, this ); return false;">getSelectedIndex</a><div class="methodContainer"> <div class="methodInfo"> <h4>Syntax</h4> <p><code><span class="object">object</span>.getSelectedIndex()</code></p> <h4>Arguments</h4> <p>No Arguments.</p> <h4>Return Type</h4> <p><code>Number</code></p> </div></div> </td> <td>The index of the selected tab page</td> </tr> <tr> <td> <a class="helpLink" href="javascript://" onclick="toggleMethodArguments( event, this ); return false;">setSelectedIndex</a><div class="methodContainer"> <div class="methodInfo"> <h4>Syntax</h4> <p><code><span class="object">object</span>.setSelectedIndex(<span class="methodArgument">n</span>)</code></p> <h4>Arguments</h4> <table> <thead> <tr> <td>Name</td> <td>Type</td> <td>Descripton</td> </tr> </thead> <tbody> <tr> <td><code>n</code></td> <td><code>Number</code></td> <td>The index of the tab page to select</td> </tr> </tbody> </table> <h4>Return Type</h4> <p><code>void</code></p> </div></div> </td> <td>Sets the selected tab page by index</td> </tr> </tbody> </table> <h3>Fields</h3> <table> <thead> <tr> <td>Name</td> <td>Type</td> <td>Descripton</td> </tr> </thead> <tbody> <tr> <td><code>classNameTag</code></td> <td><code>String</code></td> <td>This string is added to the class name to tag the tab pane as beeing created</td> </tr> <tr> <td><code>element</code></td> <td><code>HTMLElement</code></td> <td> <span class="readOnly">Read only.</span>The html element being that represents the tab pane</td> </tr> <tr> <td><code>pages</code></td> <td><code>WebFXTabPages[]</code></td> <td> <span class="readOnly">Read only.</span>An array containing the tab pages</td> </tr> <tr> <td><code>selectedIndex</code></td> <td><code>Number</code></td> <td> <span class="readOnly">Read only.</span>The index of the selected tab page</td> </tr> <tr> <td><code>tabRow</code></td> <td><code>HTMLElement</code></td> <td> <span class="readOnly">Read only.</span>The html element that encloses all tabs</td> </tr> <tr> <td><code>useCookie</code></td> <td><code>Boolean</code></td> <td>Is used to decide if the selected tab page index should be persisted using a cookie.</td> </tr> </tbody> </table> <h3>Remarks</h3> <p> None. </p> <h2>WebFXTabPage</h2> <p> This is the class representing a tab page. </p> <h3>Syntax</h3> <p><code>
new WebFXTabPage(<span class="methodArgument">oElement</span>, <span class="methodArgument">oTabPane</span>, <span class="methodArgument">nIndex</span>)</code></p> <h3>Parameters</h3> <table> <thead> <tr> <td>Name</td> <td>Type</td> <td>Descripton</td> </tr> </thead> <tbody> <tr> <td><code>oElement</code></td> <td><code>HTMLElement</code></td> <td>The html element that represents the tab page</td> </tr> <tr> <td><code>oTabPane</code></td> <td><code>WebFXTabPane</code></td> <td>The tab pane to add the page to</td> </tr> <tr> <td><code>nIndex</code></td> <td><code>Number</code></td> <td>The index of the tab page</td> </tr> </tbody> </table> <h3>Static Methods</h3> <table> <thead> <tr> <td>Name</td> <td>Description</td> </tr> </thead> <tbody> <tr> <td colspan="2">None.</td> </tr> </tbody> </table> <h3>Static Fields</h3> <table> <thead> <tr> <td>Name</td> <td>Type</td> <td>Descripton</td> </tr> </thead> <tbody> <tr> <td colspan="3">None.</td> </tr> </tbody> </table> <h3>Methods</h3> <table> <thead> <tr> <td>Name</td> <td>Description</td> </tr> </thead> <tbody> <tr> <td> <a class="helpLink" href="javascript://" onclick="toggleMethodArguments( event, this ); return false;">hide</a><div class="methodContainer"> <div class="methodInfo"> <h4>Syntax</h4> <p><code><span class="object">object</span>.hide()</code></p> <h4>Arguments</h4> <p>No Arguments.</p> <h4>Return Type</h4> <p><code>void</code></p> </div></div> </td> <td>Hides the tab page</td> </tr> <tr> <td> <a class="helpLink" href="javascript://" onclick="toggleMethodArguments( event, this ); return false;">select</a><div class="methodContainer"> <div class="methodInfo"> <h4>Syntax</h4> <p><code><span class="object">object</span>.select()</code></p> <h4>Arguments</h4> <p>No Arguments.</p> <h4>Return Type</h4> <p><code>void</code></p> </div></div> </td> <td>Selects the tab page</td> </tr> <tr> <td> <a class="helpLink" href="javascript://" onclick="toggleMethodArguments( event, this ); return false;">show</a><div class="methodContainer"> <div class="methodInfo"> <h4>Syntax</h4> <p><code><span class="object">object</span>.show()</code></p> <h4>Arguments</h4> <p>No Arguments.</p> <h4>Return Type</h4> <p><code>void</code></p> </div></div> </td> <td>Makes the tab page visible</td> </tr> </tbody> </table> <h3>Fields</h3> <table> <thead> <tr> <td>Name</td> <td>Type</td> <td>Descripton</td> </tr> </thead> <tbody> <tr> <td><code>element</code></td> <td><code>HTMLElement</code></td> <td> <span class="readOnly">Read only.</span>The html element being used as the page</td> </tr> <tr> <td><code>index</code></td> <td><code>Number</code></td> <td> <span class="readOnly">Read only.</span> The index of the tab page in the tab pane pages array. </td> </tr> <tr> <td><code>tab</code></td> <td><code>HTMLElement</code></td> <td> <span class="readOnly">Read only.</span>The html element being used as the tab.</td> </tr> </tbody> </table> <h3>Remarks</h3> <p> Do not use this constructor manually. Use addTabPage of the WebFXTabPane class instead. </p> <h2>Globals</h2> <h3>Functions</h3> <table> <thead> <tr> <td>Name</td> <td>Description</td> </tr> </thead> <tbody> <tr> <td> <a class="helpLink" href="javascript://" onclick="toggleMethodArguments( event, this ); return false;">hasSupport</a><div class="methodContainer"> <div class="methodInfo"> <h4>Syntax</h4> <p><code>hasSupport()</code></p> <h4>Arguments</h4> <p>No Arguments.</p> <h4>Return Type</h4> <p><code>Boolean</code></p> </div></div> </td> <td>Returns whether the browser is supported or not</td> </tr> <tr> <td> <a class="helpLink" href="javascript://" onclick="toggleMethodArguments( event, this ); return false;">setupAllTabs</a><div class="methodContainer"> <div class="methodInfo"> <h4>Syntax</h4> <p><code>setupAllTabs()</code></p> <h4>Arguments</h4> <p>No Arguments.</p> <h4>Return Type</h4> <p><code>void</code></p> </div></div> </td> <td> Initializes all tab panes and tab pages that have not been initialized already. </td> </tr> </tbody> </table> <h3>Objects</h3> <table> <thead> <tr> <td>Name</td> <td>Type</td> <td>Descripton</td> </tr> </thead> <tbody> <tr> <td colspan="3">None.</td> </tr> </tbody> </table> <!-- end main output -->
</div> <!-- end api tab -->
<!-- begin implementation tab --> <div class="tab-page" id="implementation-page"> <h2 class="tab">Implementation</h2> <script type="text/javascript"> tabPane.addTabPage( document.getElementById( "implementation-page" ) ); </script>
<h3>Check for support</h3>
<p>The way to check the browser whether it support a certain feature in the DOM is to use the method <code>document.implementation.hasFeature</code>. However since IE5.5 supports all the features that this script needs but it does not support this way of checking for support we have to add a separate check for IE55.</p>
<pre> function hasSupport() {
if (typeof hasSupport.support != "undefined") return hasSupport.support; var ie55 = /msie 5.[56789]/i.test( navigator.userAgent ); hasSupport.support = ( typeof document.implementation != "undefined" && document.implementation.hasFeature( "html", "1.0" ) || ie55 ) // IE55 has a serious DOM1 bug... Patch it! if ( ie55 ) { document._getElementsByTagName = document.getElementsByTagName; document.getElementsByTagName = function ( sTagName ) { if ( sTagName == "*" ) return document.all; else return document._getElementsByTagName( sTagName ); }; }
return hasSupport.support; } </pre>
<p>As you can see in the code above IE55 has a bug an therefore we also patch that. Too many people are still using IE55 to just ignore it.</p>
<h3>WebFXTabPane</h3>
<p>The constructor for the tab pane creates the <code>tabRow</code> div that is used to place all the actual tabs in. It also checks the cookie state so that the selected tab can be persisted. Besides from this it sets up some properties needed to keep track of the states. Last but not least it checks the <code>childNodes</code> of the element and adds the found tab pages.</p>
<pre> function WebFXTabPane( el, bUseCookie ) { if ( !hasSupport() || el == null ) return; this.element = el; this.element.tabPane = this; this.pages = []; this.selectedIndex = null; this.useCookie = bUseCookie != null ? bUseCookie : true; // add class name tag to class name this.element.className = this.classNameTag + " " + this.element.className; // add tab row this.tabRow = document.createElement( "div" ); this.tabRow.className = "tab-row"; el.insertBefore( this.tabRow, el.firstChild );
var tabIndex = 0; if ( this.useCookie ) { tabIndex = Number( WebFXTabPane.getCookie( "webfxtab_" + this.element.id ) ); if ( isNaN( tabIndex ) ) tabIndex = 0; } this.selectedIndex = tabIndex; // loop through child nodes and add them var cs = el.childNodes; var n; for (var i = 0; i < cs.length; i++) { if (cs[i].nodeType == 1 && cs[i].className == "tab-page") { this.addTabPage( cs[i] ); } } } </pre> <p>There are a few methods added to the <code>WebFXTabPane</code> class and one of the more important ones is the method <code>addTabPage</code>. This method takes the element that represents the tab page and uses that to create a <code>WebFXTabPage</code> object that is added to the <code>pages</code> array. Once the tab page has been added it also checks if this page is the selected one and if it is it shows it.</p> <pre> WebFXTabPane.prototype = {
... addTabPage: function ( oElement ) { if ( !hasSupport() ) return; if ( oElement.tabPage == this ) // already added return oElement.tabPage; var n = this.pages.length; var tp = this.pages[n] = new WebFXTabPage( oElement, this, n ); tp.tabPane = this; // move the tab out of the box this.tabRow.appendChild( tp.tab ); if ( n == this.selectedIndex ) tp.show(); else tp.hide(); return tp; } }; </pre>
<h3>WebFXTabPage</h3>
<p>This class is used to keep track of the actual tab page. Once created it moves the tab element to the <code>tabRow</code> of the tab pane. It also adds an anchor around the text so that the user can use the keyboard to activate the tabs.</p>
<pre> function WebFXTabPage( el, tabPane, nIndex ) { if ( !hasSupport() || el == null ) return; this.element = el; this.element.tabPage = this; this.index = nIndex; var cs = el.childNodes; for (var i = 0; i < cs.length; i++) { if (cs[i].nodeType == 1 && cs[i].className == "tab") { this.tab = cs[i]; break; } } // insert a tag around content to support keyboard navigation var a = document.createElement( "A" ); a.href = "javascript:void 0;"; while ( this.tab.hasChildNodes() ) a.appendChild( this.tab.firstChild ); this.tab.appendChild( a ); // hook up events, using DOM0 var oThis = this; this.tab.onclick = function () { oThis.select(); }; this.tab.onmouseover = function () { WebFXTabPage.tabOver( oThis ); }; this.tab.onmouseout = function () { WebFXTabPage.tabOut( oThis ); }; } </pre>
<h3>Initialization</h3>
<p>The initialization uses the global function <code>setupAllTabs</code> that goes through all elements and checks their class names and if the class names match the classes used by the tab pane controls it checks whether this element belongs to an uninitialized control and in that case it initializes it now.</p>
<pre> function setupAllTabs() { if ( !hasSupport() ) return;
var all = document.getElementsByTagName( "*" ); var l = all.length; var tabPaneRe = /tab-pane/; var tabPageRe = /tab-page/; var cn, el; var parentTabPane; for ( var i = 0; i < l; i++ ) { el = all[i] cn = el.className;
// no className if ( cn == "" ) continue; // uninitiated tab pane if ( tabPaneRe.test( cn ) && !el.tabPane ) new WebFXTabPane( el ); // unitiated tab page wit a valid tab pane parent else if ( tabPageRe.test( cn ) && !el.tabPage && tabPaneRe.test( el.parentNode.className ) ) { el.parentNode.tabPane.addTabPage( el ); } } } </pre>
<p>This function can be called manually at any time but the script makes hooks to the <code>load</code> event for the window. This is done using DOM level 2 events if available. If not we test if it supports the IE5 way of attaching events and last we fall back on classic way of setting events.</p>
<pre> // DOM2 if ( typeof window.addEventListener != "undefined" ) window.addEventListener( "load", setupAllTabs, false );
// IE else if ( typeof window.attachEvent != "undefined" ) window.attachEvent( "onload", setupAllTabs );
else { if ( window.onload != null ) { var oldOnload = window.onload; window.onload = function ( e ) { oldOnload( e ); setupAllTabs(); }; } else window.onload = setupAllTabs; } </pre>
</div> <!-- end implementation tab -->
<!-- begin look and feel tab --> <div class="tab-page" id="look-page"> <h2 class="tab">Look & Feel</h2> <script type="text/javascript"> tabPane.addTabPage( document.getElementById( "look-page" ) ); </script>
<h3>The structure</h3>
<p>To be able to change the look and feel one needs to understand the structure of the tab pane. When the original XHTML source tree is transformed into the tab pane the class name of the element representing the tab pane is tagged with the property <code>classNameTag</code>. The default tag is <code>dynamic-tab-pane-control</code> and therefore all your css rules should take this into account. If you want different look on different tab panes in the same document this tag can be changed to make the css rules easier to set up.</p>
<pre> <div class="dynamic-tab-pane-control tab-pane" id="tab-pane-1"> <div class="tab-row"> <h2 class="tab selected"><a ... >General</a></h2> <h2 class="tab hover"><a ... >Privacy</a></h2> </div> <div class="tab-page"> This is text of tab 1. This is text of tab 1. This is text of tab 1. This is text of tab 1. </div>
<div class="tab-page"> This is text of tab 2. This is text of tab 2. This is text of tab 2. This is text of tab 2. </div> </div> </pre>
<p>The selected tab will have the class name <code>tab selected</code> and the tab that the mouse hovers over will have the class name <code>tab hover</code>. If the selected tab is hovered it will have the class name <code>tab selected hover</code>. These rules allow you to differentiate the look of tabs between the different states.</p>
<h3>The CSS Rules</h3>
<p>Here we will walk through the <a href="css/tab.winclassic.css">Windows Classic css file</a>. First we set the width and position of the tab pane to prevent a few rendering bugs in IE6.</p>
<pre> .dynamic-tab-pane-control.tab-pane { position: relative; width: 100%; }
.dynamic-tab-pane-control .tab-row { z-index: 1; white-space: nowrap; } </pre>
<p>Then we setup the css for the tab. Notice how the position is set to relative to allow the top position to be slightly changed and to allow the z-index property to be changed to position the tabs below the tab pages.</p>
<pre> .dynamic-tab-pane-control .tab-row .tab { font: Menu; cursor: Default; display: inline; margin: 1px -2px 1px 2px; float: left; padding: 2px 5px 3px 5px; background: ThreeDFace; border: 1px solid; border-color: ThreeDHighlight ThreeDDarkShadow ThreeDDarkShadow ThreeDHighlight; border-bottom: 0; z-index: 1; position: relative; top: 0; } </pre>
<p>For the selected tab we set the z-index to 3 to put it above the tab pages. We also move it a little and change some other properties to make it look more like the classic window tab control.</p>
<pre> .dynamic-tab-pane-control .tab-row .tab.selected { border-bottom: 0; z-index: 3; padding: 2px 6px 5px 7px; margin: 1px -3px -2px 0px; top: -2px; } </pre>
<p>Then we override the text properties on the tabs as well as for the <code>.hover</code> rule.</p>
<pre> .dynamic-tab-pane-control .tab-row .tab a { font: Menu; color: WindowText; text-decoration: none; cursor: default; }
.dynamic-tab-pane-control .tab-row .hover a { color: blue; } </pre>
<p>Then we set the z-index for the tab pages to 2 so that it will be shown above tabs but below the selected tab. We also set the borders and and a few other properties.</p>
<pre> .dynamic-tab-pane-control .tab-page { clear: both; border: 1px solid; border-color: ThreeDHighlight ThreeDDarkShadow ThreeDDarkShadow ThreeDHighlight; background: ThreeDFace; z-index: 2; position: relative; top: -2px; color: WindowText; font: MessageBox; font: Message-Box; padding: 10px; } </pre>
</div> <!-- end look and feel tab -->
</div> <!-- end tab pane -->
<p class="author">Author: Erik Arvidsson</p>
<!-- end webfx-main-body --> </div>
</body> </html>
|