I needed a tab pane to put some content in my web pages. There are many solutions around and I must say that they are quite good, but I had some extra requirements that I needed. I did search around but I did not find what I wanted, so I ended up producing something and now I am sharing it with you. The idea is not just to share the code but also explain the issues involved.
This is quite a Web 2.0 thing, and I must say it was not an absolute requirement, but since I am at it I may as well do it in a good way.
The requirement is that the content of the panels should be downloaded with the page that defines the panels and therefore when the user switches panels there will not be any delay, the content is already there.
Quite a few of the tabbed panels around basically take over the content. This simply means that you design the page around the tabbed pane and it is quite difficult to put extra content in it.
I wanted a tab panel that fits inside some content I have and not one that takes over my page. Note that this means avoiding as much as possible fixed width and height and using as much as possible all the available screen size. Not easy...
Before giving you the solution I will describe the issues involved, so you can understand better what the code does and change it to suit your needs.
I could have stored the content in a Javascript variable and then push it into the current DIV (this may be something I do in the future) but as it is now I am inserting the content of the different panels into different DIV, each one having a separate ID. This surely makes writing the actual content of the panel easy.
This is kind of simple, the way to overlap content is by means of using a DIV set to relative positioning and then putting inside it some DIV set to absolute positioning. The inserted DIV will overlap one on top of each other. You may wish to look at the official CSS visual formatting model reference.
This is now done all in Javascript but at the beginning I followed the example given by nontroppo.org that uses the hover part of the anchor tag to change the color. The effect is quite good although I was a bit annoyed by the hash at the end of the URL and the CSS part of it is quite messy.
So I changed the list/anchor with span and attached event handling to it. The handled events are
The somewhat difficult part was changing the visual appearance of the span from javascript. This is not as easy as it seems since Javascript lacks many of the setters method available from CSS. The solution is to create a special CSS class that describes the new visual appearance and then set it to the span using Javascript. Being a bit careful with CSS the code results remarkably clean.
This is a bit complicated. The problem is that once the DIV are in absolute positioning they kind of lose the capability of sizing themself depending on the size of the content box. This is according to specification and I must say it is a bit annoying.
There are two sizes to take care of, the vertical and the horizontal and to manage them I had to create an extra DIV beside the actual content that is used to actually reserve the correct space in the main html page. This DIV is then used by the Javascript code to size the actual content pane with the appropriate values.
The concept is therefore that when the page is resized the tab panel size is set based on the size of the filler DIV. It is a simple concept that should work with any decent browser. It would be nice if you could tell me with what browser it works, I will add it at the end of the list. Finding the right pieces of javascript DOM is not easy, I should say thanks you to quirks mode for their good page on Javascript size properties.
Below there is an example of the panel, look at the source code of the page !
Veni Karthaginem, et circumstrepebat me undique sartago flagitiosorum amorum. nondum amabam, et amare amabam, et secretiore indigentia oderam me minus indigentem. quaerebam quid amarem, amans amare, et oderam securitatem et viam sine muscipulis, quoniam fames mihi erat intus ab interiore cibo, te ipso, deus meus, et ea fame non esuriebam, sed eram sine desiderio alimentorum incorruptibilium, non quia planus eis eram, sed quo insanior, fastidiosior. et ideo non bene valebat anima mea, et ulcerosa proiciebat se foras, miserabiliter scalpi avida contactu sensibilium.
sed si non haberent animam, non utique amarentur. amare et amari dulce mihi erat, magis si et amantis corpore fruerer. Venam igitur amicitiae coinquinabam sordibus concupiscentiae, candoremque eius obnubilabam de tartaro libidinis, et tamen foedus atque inhonestus, elegans et urbanus esse gestiebam abundanti vanitate. rui etiam in amorem, quo cupiebam capi. deus meus, misericordia mea, quanto felle mihi suavitatem illam et quam bonus aspersisti, quia et amatus sum, et perveni ad vinculum fruendi et conligabar laetus aerumnosis nexibus, ut caederer virgis ferreis ardentibus zeli et suspicionum et timorum et irarum atque rixarum.
To use it you have to attach the following pieces to your page
You attach the CSS writing the following code into the HEAD section of your page
<link rel="stylesheet" href="tab-panel.css" type="text/css" />
And you attach the javascript using the following code, again in your HEAD section
<script language="JavaScript" type="text/javascript" src="tab-panel.js"> </script>
The last part is to attach the proper loading function to the body
<body onload="bodyOnLoad()" onResize="raisePanel(currentMenuIndex)">
This should be all you need to do, really. I am not going to complain here about the complexity of all of this I still believe that browser compatibility is a major issue, in any case I have tested this page with the following browsers ... and it works !
Let me know if you like it, I will post comments below.
If you want to be contacted then leave an address
Last update 23/02/2007