Tabs, Revisited

I wrote a blog entry a couple of days ago on how to build a tabbed window setup using only standard JSF components.

The solution used one page per tab. That's okay for a web application where you really want to have separate contents on each and every page. But what if you want to have multiple tab sections on each page? Or what if the tab area represents only a small portion of the page - you would have to put all the shared contents in a page fragment.

Here's an alternative solution. I'm just going to outline it, since I think that will be sufficient - but if anyone has trouble, feel free to ask follow-up questions - you can post anonymous comments if you are embarassed :-)

Like before, you'll create a set of tabs by putting Link Action components inside a horizontal grid panel. However, this time, instead of putting the separate tab contents on separate pages, you will place all of the tabs in this page, all on top of each other! Then, all of these components will be "turned off", except for the one which corresponds to the current tab! We can turn off components by using the "rendered" property on the JSF components.

So let's begin. As before, create a grid panel, decide how many tabs you want, drop a link action for each, and set the embedded Output Text values to the tab names.

For the links however, instead of using navigation, double click on each link to create action handlers. In the action handler for the third link for example, write something like this:

     currentTab = 3;
You also need to add an integer variable named currentTab to your page bean:
     private int currentTab;

Next you need to go and add the tab contents. Drop a Grid Panel right under the tab-link-panel Then go and look for its "Rendered" property (it's probably under Advanced) and uncheck it. The component should now disappear. Repeat this process such that you have created as many grid panels as you have tab links. Now go and re-enable the Rendered property on one of them. Then drop components inside this grid panel as appropriate to populate your tab contents.

Note that you won't be able to use "absolute positioning" (where you can drag & drop components anywhere) inside these tabs. If you want to do that, create page fragments for these, and then put the page fragment box inside a panel group component in the grid.

The final thing we need to do is hook up the Rendered properties such that they get enabled exactly when the corresponding link is selected. To do that, make our currentTab variable into a property by adding this method to your page bean:

     public int getCurrentTab() {
         return currentTab;
Now you can change the "Rendered" property for the grid panel number 3 (corresponding to tab link number 3) from "off" to this value binding expression:
You do this by right clicking on the grid panel in the Application Outline, choose Property Bindings..., select the Advanced radio button, and then paste the above into the "New binding expression" textfield on the bottom. Yes - notice the flexibility in the expression language - we can do comparisons (in addition to a number of other operations. To learn more about this, open up the Help dialog in Creator, switch to the Search box and search for "Expression Language".)

You would obviously adjust this if your page name is something other than "Page1", and of course the "3" should be adjusted for each link.

Finally, you need to highlight the tab names and use CSS to make the cells look like tabs. This is precisely like the last time, so I won't cover it here. You only have to modify the code which goes and figures out which tab is current. Last time I had to search to the view root and compare tab names. That is not necessary now - we know the tab index directly since we set it in the links!

That's all there is to it - it should work. Note that the designtime experience here is harder, because once you've value bound the Rendered properties for each tab section, they don't show up at designtime. You can temporarily set them back to true, edit, then enable value binding again. Or, if you use page fragments you can edit the layout by opening the fragments file.

Good luck!

P.S. In the above I referred to the "third" link and showed an integer of "3", for simplicity. Remember that the tab index code is 0-based, so you would really set currentTab=2, compare with ==2 in the value binding expressions, etc.


Tor, Can you (or a netbeans developers) please write a small tutorial that demonstrates how to use subversion in netbeans. Thanks

Posted by guest on April 08, 2005 at 01:50 PM PDT #

Sorry, I don't use subversion, but perhaps this pointer helps?

Posted by Tor Norbye on April 11, 2005 at 03:15 PM PDT #

Post a Comment:
Comments are closed for this entry.

Tor Norbye


« July 2016