Monday April 04, 2005 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:
#{Page1.currentTab==3}
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.
(2005-04-04 22:20:05.0) Permalink Comments [2]
It's awards season again - and Java Developer's Journal is conducting a product survey.
Creator is nominated in the "Most Innovative Tool" category.
Of course, voluntary participation surveys like these are NOT scientific. But since placing well in these kinds of contests helps marketing (or, if you don't do well, helps the competition), everybody seems to try to encourage their users to participate anyway. I see that at least one of the other nominees in the same category is displaying a link to vote prominently on their site, so I don't feel too bad encouraging you to do the same. (In a quick spot check I also see links to the poll on both IntelliJ's site and WebSphere's site.
If you feel Creator has innovated in the java tools category and is making your job easier, please consider going to http://sys-con.com/java/readerschoice2004/index.cfm and casting a vote for Creator.
And while you're there, consider many of the other Sun technologies that are nominated as well.
(2005-04-04 16:53:25.0) Permalink