Today's Episode:
Tabs, Tabs, everywhere...
As part of the same web-enabling job that was the subject of my previous excursion into the world of Strange Code, I was faced with multiple windows implemented as a Windows-style tabbed interface. Several had the tabs on multiple rows. The interface had to behave over the web exactly as it had under the previous client. I still had the same time limitations on coding it in Java as I did previously.
In other words, I had a big problem.
Fortunately, recent work at webbuilder.netscape.com looked like it would be most helpful to me. They carried not one, but two recent articles on building tabbed interfaces. The second one was of immediate interest, since it allowed for multiple rows of tabs. There were some problems with the technique they presented, though:
- the tabs (implemented as <DIV> blocks) were fixed width and required precise positioning on the document
- the rows did not move down next to the content area as a tab within them was selected
- the content areas associated with each tab were implemented within <DIV> blocks. Code associated with each tab toggled the display attribute of the associated content block
While I could live with the first two problems (with much gritting of teeth), the third had massive impacts all through the project. First, I would have to pull data for all content blocks from the backend database at page load. Then, the amount of Perl I was going to have to write to supervise database access and reformat the output was going to be non-trivial. The product of both these impacts would cause Apache to consume lots of memory servicing the user's request that would otherwise have been better used. Ouch.
Several flashes of inspiration then hit me:
- Use the <IFRAME> tag to display content
- I can now split the content (and neccessary Perl routines and database accesses) among several files. Instead of being totally dependent on a single massive Javascript handler to manage each page of content, I can use a simple <A> tag and a <BASE TARGET=''> directive in the HEAD block to do the same thing.
- Use the <SPAN> tag for the tabs
- Immediately, I don't have to worry anymore about precisely fixing each tab's width and horizontal position. Additionally, since both Netscape and IE's event handling model allow multiple nested blocks to act on a single event, I can set a simple
onclickhandler for the tab whose only job is to make it appear selected whenever the user clicks on the contained link. - Put each row of tabs within a <DIV> block
- By doing this, I can now set the vertical position of the entire row of tabs at one time. I can also exploit the nature of Netscape and IE's event handling model again by setting another simple
onclickhandler whose only job is to flip the position and z-index of the current and selected row.
I think the end result works quite nicely. If you want to look behind the scenes at what it's doing, use your browser's View Source command and enjoy.
BUGS FEATURES
This technique lives and dies on its use of the <IFRAME> tag to display content. With some work, it can be made to work with the <FRAME> and <FRAMESET> tags. The proof is left as an exercise for the reader.
The colors and borders chosen for each style also may not render quite right on your browser. Fiddle with the appropriate parameters and season to taste if these are problems.
The tabs render weird on IE 5 for the Macintosh. This is due to the way it chooses to render the border styles