Well, Bertrand's Accordian example inspired me last night, so I came up with a client-side Atlas tabstrip. It basically supplants the Microsoft tabstrip, which I have come to despise over the last few years :) It works in both IE and Mozilla. I don't really have anywhere to post this, so here it is:
You can call this file something like TabSet.js
Type.registerNamespace(
'Dice');
// Tabset view
Dice.Tabset = function(associatedElement) {
Dice.Tabset.initializeBase(this, [associatedElement]);
var _viewIndex = 0;
var _selectedTabStyle = '';
var _viewHeads = [];
var _viewPanes = [];
var _viewClickHandler;
this.get_viewIndex = function() {
return _viewIndex;
}
this.set_viewIndex = function(value) {
if (_viewIndex != value) {
_viewIndex = value;
_ShowCurrentPane.call(this);
this.raisePropertyChanged('viewIndex');
}
}
this.get_selectedTabStyle = function() {
return _selectedTabStyle;
}
this.set_selectedTabStyle = function(value) {
_selectedTabStyle = value;
}
this.dispose = function() {
if (_viewClickHandler) {
for (var i = _viewHeads.length - 1; i >= 0; i--) {
var head = _viewHeads[i];
if (head) {
head.detachEvent('onclick', _viewClickHandler);
}
}
delete _viewClickHandler;
delete _viewHeads;
delete _viewPanes;
}
Dice.Tabset.callBaseMethod(this, 'dispose');
}
Dice.Tabset.registerBaseMethod(this, 'dispose');
this.initialize = function() {
Dice.Tabset.callBaseMethod(this, 'initialize');
_viewClickHandler = Function.createDelegate(this, _onViewClick);
// Get tabstrip first.
var tabstrip;
var panes;
var children = this.element.childNodes;
for (var i = 0; i < children.length; i++) {
var child = children[i];
if (child.nodeName == 'UL') {
tabstrip = child.childNodes;
break;
}
}
for (var i = 0, p = 0; i < tabstrip.length; i++) {
var child = tabstrip[i];
if (child.nodeName == 'LI') {
_viewHeads.add(child);
child.viewIndex = p++;
child.attachEvent('onclick', _viewClickHandler);
}
}
for (var i = 0; i < children.length; i++) {
var child = children[i];
if (child.nodeName == 'DIV') {
_viewPanes.add(child);
}
}
_ShowCurrentPane.call(this);
}
Dice.Tabset.registerBaseMethod(this, 'initialize');
function _onViewClick() {
var pane = window.event.srcElement;
while (pane && (typeof(pane.viewIndex) == 'undefined')) pane = pane.parentNode;
this.set_viewIndex(pane.viewIndex);
return false;
}
function _ShowCurrentPane() {
for (var i = _viewPanes.length - 1; i >= 0; i--) {
var selectedTab = _viewHeads[i];
var pane = _viewPanes[i];
if (i != _viewIndex) {
selectedTab.className = '';
pane.style.display = 'none';
} else {
selectedTab.className = _selectedTabStyle;
pane.style.display = 'block';
}
}
}
this.getDescriptor = function() {
var td = Dice.Tabset.callBaseMethod(this, 'getDescriptor');
td.addProperty('viewIndex', Number);
td.addProperty('selectedTabStyle', String);
return td;
}
Dice.Tabset.registerBaseMethod(this, 'getDescriptor');
}
Dice.Tabset.registerClass(Dice.Tabset', Sys.UI.Control);
Sys.TypeDescriptor.addType(dice, 'tabset', Dice.Tabset);Make sure you add a reference to the file in your <atlas:scriptmanager> tag.
Then, on the page where you want to use the control, add this:
<script type="text/xml-script">
<page xmlns:script="http://schemas.microsoft.com/xml-script/2005" xmlns:dice="dice">
<components>
<dice:tabset id="productTabset" selectedTabStyle="selected"/>
</components>
</page>
</script>
Then, add your HTML for the tabset:
<div id="productTabset">
<ul>
<li>Tab 1</li>
<li>Tab 2</li>
<li>Tab 3</li>
<li>Tab 4</li>
</ul>
<div class="pane">
First Tab
</div>
<div class="pane">
Second Tab
</div>
<div class="pane">
Third Tab
</div>
<div class="pane">
Fourth Tab
</div>
</div>
The unordered list will become the tabs, and the divs will become the panes.
You can style the tabs any way you want. Here's a sample style sheet you can use:
/* Tabset */
div#productTabset ul
{
display: block;
margin: 0;
padding: 0;
text-align: left;
width: 600px;
}
div#productTabset li
{
background-color: #ece9d8;
border: solid 1px black;
border-bottom: none;
cursor: pointer;
display: block;
float: left;
font-weight: bold;
height: 15px;
list-style: none;
margin: 0 -1px 0 0;
padding: 3px;
position: relative;
width: 100px;
z-index: 97;
}
div#productTabset li.selected
{
background-color: White;
border-bottom: none;
position: relative;
z-index: 100;
}
div#productTabset .pane
{
border: solid 1px black;
clear: both;
display: none;
overflow: auto;
padding: 5px;
position: relative;
width: 588px;
height: 300px;
top: -1px;
z-index: 99;
}
I'm not giving any kind of support for this control, so you're on your own. It's a foundation you can customize to your own needs, and a nice way to learn the client-side stuff in Atlas.
Have fun!