How to Create Spry Tabbed panels with the tabs at the bottom
Spry Tabbed panels in 1.6.1 allow you to have your tabs at the top or on the left. Dreamweaver CS3 & CS4 (try the CS4 beta) will allow you to insert the tabs on the top, but it's pretty easy to change to vertical tab on the left by swapping out the class for the widget wrapper from TabbedPanels to VTabbedPanels. See the Spry Tabbed Panels documentation for more info on how the default tabbed panels work.
However, if you want you tabs to appear on the bottom of the panels, then you're outta luck, by default that is. Fortunately the Tabbed Panels are pretty easy to tweak to allow you to have your tabs on the bottom, by making three small changes. The first is to reorder the code that comprises the widget such that the container for the tabs is after the container for the panel content. So you move from:
<div id="TabbedPanels1" class="TabbedPanels">
<ul class="TabbedPanelsTabGroup">
<li class="TabbedPanelsTab" tabindex="0">Tab 1</li>
<li class="TabbedPanelsTab" tabindex="0">Tab 2</li>
<li class="TabbedPanelsTab" tabindex="0">Tab 3</li>
<li class="TabbedPanelsTab" tabindex="0">Tab 4</li>
</ul>
<div class="TabbedPanelsContentGroup">
<div class="TabbedPanelsContent">Content 1</div>
<div class="TabbedPanelsContent">Content 2</div>
<div class="TabbedPanelsContent">Content 3</div>
<div class="TabbedPanelsContent">Content 4</div>
</div>
</div>
To:
<div id="TabbedPanels1" class="TabbedPanels">
<div class="TabbedPanelsContentGroup">
<div class="TabbedPanelsContent">Content 1</div>
<div class="TabbedPanelsContent">Content 2</div>
<div class="TabbedPanelsContent">Content 3</div>
<div class="TabbedPanelsContent">Content 4</div>
</div>
<ul class="TabbedPanelsTabGroup">
<li class="TabbedPanelsTab" tabindex="0">Tab 1</li>
<li class="TabbedPanelsTab" tabindex="0">Tab 2</li>
<li class="TabbedPanelsTab" tabindex="0">Tab 3</li>
<li class="TabbedPanelsTab" tabindex="0">Tab 4</li>
</ul>
</div>
This change allows for easy display of the tabs at the bottom, because the tabs are now below the content panels.
Then you need to tweak the CSS a bit. You can change the code in the SpryTabbedPanels.css, but you may need the default for some other tabbed panel instance. So if you add the following style block to your page (or add it to a separate CSS file):
<style type="text/css">
<!--
.TabbedPanelsTab {
position: relative;
top: -1px;
float: left;
padding: 4px 10px;
margin: 0px 1px 0px 0px;
font: bold 0.7em sans-serif;
background-color: #DDD;
list-style: none;
border-left: solid 1px #CCC;
border-bottom: solid 1px #999;
border-top: solid 1px #999;
border-right: solid 1px #999;
-moz-user-select: none;
-khtml-user-select: none;
cursor: pointer;
}
.TabbedPanelsTabSelected {
background-color: #EEE;
border-top: 1px solid #EEE;
}
-->
</style>
If you compare the selectors to the matching styles in SpryTabbedPanels.css (.TabbedPanelsTab selector lines 67-83, and .TabbedPanelsTabSelected selector lines 105-108), you'll note that there are only two changes, moving from "top:1px;" to "top:-1px" for .TabbedPanelsTab and moving from "border-bottom: 1px solid #EEE;" to "border-top: 1px solid #EEE;". These changes will allow the bottom tab to overlap the bottom of the content making it look seamless for the "selected" tab.
So two down, one to go. The next change is in the JavaScript to allow the Spry Tabbed Panales widget to recognize the reordered tabs and content panels. As with the CSS, I'm putting this code into the page itself rather than modify the Spry files. Add the following to your page (pulled from SpryTabbedPanels.js lines 124-133 and lines 144-153):
<script type="text/javascript">
<!--
Spry.Widget.TabbedPanels.prototype.getTabGroup = function()
{
if (this.element)
{
var children = this.getElementChildren(this.element);
if (children.length)
return children[1];
}
return null;
};
Spry.Widget.TabbedPanels.prototype.getContentPanelGroup = function()
{
if (this.element)
{
var children = this.getElementChildren(this.element);
if (children.length > 1)
return children[0];
}
return null;
};
-->
</script>
The only changes here are moving from "return children[0];" to "return children[1];" in Spry.Widget.TabbedPanels.prototype.getTabGroup.
Both changes reflect the change in order of the tabs and the content panels within the Tabbed panel wrapper div (<div id="TabbedPanels1" class="TabbedPanels"></div>).
Save and preview your page and viola, bottom tabs on your Spry Tabbed Panels.
A couple of things to keep in mind. Dreamweaver won't properly display your tabs and content panels in design view, so you'll lose a bit there, and if your content panels are of differing heights, sat tab 1 content is 200 pixels high and tab 2 is 50 pixels high, then switching tabs will cause the bottom of the tabbed panels to move up and down (taking with them the tabs too).
The former issue can't be worked around without mucking about a good int in Dreamweaver's internals, the second probably can be worked around by setting specific heights for the content areas and then maybe setting an overflow:scroll to allow for content that is too tall to the height you set. I haven't tested that type of change, but should be something like that.
Labels: Spry


14 Comments:
Nice article mate. You mentioned the display issues with Dreamweaver in design view - I often find that happens for no apparent reason. I get divs pushed down in design view, often when there is a Spry menu. However it all works perfectly in browser.
Do you know by any chance what Adobe intend to do with Fireworks? I love that program and I hope they aren't going to neuter it in favour of Photoshop.
As there is a Fireworks CS4 beta on their Labs site, I'd say that Adobe is investing in Fireworks. You'll need a CS3 serial number to be able to use it for more than a couple of days. I've not investigated the CS4 beta much, so can't really tell you what all has been added that may be worth it to you, but I'd suggest taking a look at the release notes page for the Fireworks CS4 beta to see what has been added or improved and grab the beta to play around with it.
Great post! I'm extremely new to the development world and your post gave me the guidance to push through a trouble spot.
I ran into another problem and know one seems to have an answer for it. When i'm editing the external css style sheet for this spry, I keep recieving a sharing violation. It stops me from saving the style sheet? Any ideas?
Hi,
I've been searching high and low for advice on adding certain Spry effects to the Spry tabbed panels widget, and have found very little. basically, i want to add one of the default spry effects as a transition between the tabbed panels (a fade effect). i know the collapsible panels widget has animation built in, but is it possible to add transition effects to the tabbed panels widget? or is that simply not supported unless you can write code from scratch? (!)
any help would be much appreciated!
Kyle
@Kyle,
The showing and hiding of tabbed panels is in deed baked in, and so you'd need to re-write the Spry.Widget.TabbedPanels.prototype.showPanel method to be able to add in any animation effects you'd like to have.
This could be a good topic to look into for my presentation at MAX in November.
@mydayregistry,
Sorry, I've never seen that sharing violation error. I'd check for file permissions in the Spry folder contents, and then do some Google searches for "Dreamweaver sharing violation".
This post has been removed by the author.
Hi Danilo, thanks for your help, I'll definitely leave it well alone for now!
One other question though: is it possible to set spry tabbed panels to all be closed by default? i don't really want the content showing until one of the three tab buttons is clicked (you can see the page if that helps at: http://thing.websitewelcome.com/~createde/showcase.html
i realise that collapsible panels can be closed by default, but i want the layout functionality of tabbed panels... is there a fix you know of?
thanks again,
Kyle
@Kyle,
Just checked your page and it seems that you've found a way to do this by adding a "hidden" tab, one that has no content for the tab itself, and nothing in the content area.
I did a little looking and there is a option for the constructor that allows you to set the default tab, and that assumes that you're using an integer to identify the tab. So if you pass in 0.5 or even an empty string as the defaultTab option, then no tab content areas will show:
var TabbedPanels1 = new Spry.Widget.TabbedPanels("TabbedPanels1", {defaultTab:0.5});
or
var TabbedPanels1 = new Spry.Widget.TabbedPanels("TabbedPanels1", {defaultTab:''});
But I do like the hidden tab that you've come up with, as it doesn't require "breaking" the options parameter of the Tabbed panel, because you never know when they might "fix" defaultTab option so that it will only work with integers, and will ignore non-integers or strings.
Hi Danilo!
I would be so grateful if you could tell me if and in how I could manipulate the Spry Widget to make it select a specific tab (and its subcontent) on a specific page load.
See my page here using the standard Spry meny widget in Dreamweaver: http://www.narrativemedia.eu/ny/index.shtml
The default selection is always the tab on the very left no matter which link I click. What I would like to do is maintain the tab selection and its subcontent on the linked page until I click another tab.
For exampel, starting on the index.shtml page above: When I click the tab "Artiklar, krönikor & debatt" the tab is selected and its subcontent is shown (several links). When I click one of the links in the subcontent I would like the tab selection to maintain status "selected" as that linked page loads.
As it is now, whenever I click a link in a tab's subcontent the tab menu defaults back to selecting the tab on the very left. This is a bit confusing and not very user friendly.
@fredrik,
Keeping the selected tab between pages can be handled using the URL Utilities. Take a look at the code on the URL Utilities sample page (look at the very bottom of the page)
You can get to that page from the Spry Samples page, then click Utilities.
Essentially, what you need to do is to add to each link that you want to be able to trigger a specific tab a query string parameter, in the example, it is panel=1, where the number is the index of the tab to show. Remember that JavaScript uses a zero (0) based index, so the first panel is 0, second is 1, etc.
Danilo, thank you for your advice
But I'm not able to make it work. I'm not so good with mathematical logic :). All I get is a broken widget and a graphical mix of the tab 0 subcontent and the content of the tab I would like to get selected.
Go to the page and click tab "Artiklar, krönikor & debatt" and then in the subcontent click link "Digital moral (krönika)" and see what happens.
Maybe I'm confused since I'm not completely sure where on which pages to put the panel=1 reference and the script respectively.
fredrik,
Looks like you're not adding the ?panel=x to the query string of your links within the tab content, and it looks like your pages are not including a link to the SpryURLUtils file as described in the URL Utilities sample.
But this isn't a good place to continue with your problem. I'd suggest asking your question in the Spry forums. Before you do, I'd suggest making a demo page that is a copy of Spry URL Utils sample page using the example at the bottom of the page and then trying to fit your content into that example to see how it works.
Great article - the comments are also very useful. Quick question - I am using the tabbed panels as a horizontal menu, which looks great; I changed the code to use mouseover to change the tab (instead of onclick). The only problem now is, as some users move from the tab to the content, if the mouse moves over another tab that gets activated. Can you think if a simple way to add a delay on the onmouseover/onmouseout to reduce this happening? I think it could be easy, but my java is not up to it...
@paul,
What you are looking for should be possible, but I don't have a ready answer for you, so from that score I dont' have a quick fix for you.
If I have some time I'll see if I can work up such a beast, and I'll make a new post about it if I do.
Perhaps you should take a look at the code for the Spry menus as they do have timer code that delays the closing of the sub-menus when you mouse out of them.
Beyond that, checkout the Spry forums someone there may have a ready answer for you.
Post a Comment
Links to this post:
Create a Link
<< Home