The ICEfaces Tutorial
Table of Contents


Lesson: Using the panelTabSet component

How to Use the ICEfaces Panel Tabset Component

The panelTabSet component can be used to display a series of tabs, either with repeating content or unique elements inside each tab. The panelTabSet component is similar to a dataTable, except ice:panelTab is used instead of h:column. In addition to iterative components, panelTabSet supports specific elements inside each tab. The following screen shot is of the ice:panelTabSet component using the CSS XP theme in the Acronym Game login screen.

panelTabSet component in Acronym Game application

The panelTabSet does not require any beans specific to the application. For example, static text can be used inside each tab using only page level tools, which removes the complexity of bean setup. In the case of each example in this tutorial, a backing bean will be used to allow greater flexibility in the content and labels of tabs.

The rest of this tutorial will discuss the following topics:

Creating a Specific Panel Tabset

The easiest Panel Tabset setup is to use specific components and elements inside of each ice:panelTab. In this next example the page contains an ice:panelTabSet and 3 generic ice:panelTab components inside each tab. Although the text content and labels of each tab could be hardcoded on the page, we will setup 2 backing beans. The first is a basic session bean that generates the default tabs and allows for future extensibility. The second bean is Tab.java, which stores the labels and content for a single tab. The following screenshot shows what the page looks like once the beans are properly setup.

Basic Panel Tabset Example

To bind the beans to the page, a simple ice:panelTabSet must first be created.

   <ice:panelTabSet>

For now we do not specify any attributes for the Panel Tabset, and so the tag is very bare and simple. The next step is to add each tab inside of the ice:panelTabSet we just created. This will also be the first bean interaction so far.

    <ice:panelTab label="#{tabset.tabs[0].label}">
        <ice:outputText value="#{tabset.tabs[0].content}"/>
    </ice:panelTab>

This will create a single tab with the label and content matching the first item in tabset.tabs list. Once 3 such tabs have been added to the ice:panelTabSet, and all necessary JSF setup code, the page will be similar to basicTabset.jspx

Download the demo:

As you may have noticed, the list based setup of TabsetBean.javalends itself to an iterator on the page. The next section will show how to use the built in iterator functionality of panelTabSet.

Creating an Iterative Panel Tabset

The similarities to a dataTable are even more prevalent when the panelTabSet iterator functionality is used. As with dataTable, a value and var attribute are set for the ice:panelTabSet tag, as shown below.

    <ice:panelTabSet var="currentTab" value="#{tabset.tabs}">

This will bind the ice:panelTabSet to the backing bean list of tabs. The currentTab name can then be used inside of the panelTabSet tag instead of hardcoding an index (as was done in the previous example). Instead of requiring 3 specific tabs, a single ice:panelTab can be used to outline the content that will be displayed on each iteration. The ice:panelTab therefore is:

    <ice:panelTab label="#{currentTab.label}">
        <ice:outputText value="#{currentTab.content}"/>
    </ice:panelTab>

The iterative approach to Panel Tabset is used in the Dynamically Adding or Removing Tabs example below.

The appearance of these 2 examples is rather generic and may not suit your application. The next section will demonstrate how to customize the CSS for panelTabSet.

Customizing Panel Tabset Styles

The tab styles can be customized by overriding the default CSS values. The first step is to create a new stylesheet and link to it in styleTabset.jspx, as shown in the line below:

    <link href="./override.css" rel="stylesheet" type="text/css"/>

Next the default tab styles should be copied into the override sheet. To find the default styles, look inside the CSS normally linked to, which is ./xmlhttp/css/xp/xp.css. Copy all tab related styles into a new sheet, in our case override.css.

The current implementation of Panel Tabset uses a series of images to create the illusion of a tab. Because of this, the image files in the css-images folder must be copied over. Of course this could be changed to use colors, gradients, or anything the designer wants.

After this is done, you can begin customizing the styles. This demonstration changes the top border colors to blue (selected tab), red (mouse over), and green (deselected tab), as shown below:

Style Panel Tabset Example

For the above example, changing the iceTabSetTabOn class to the following resulted in a blue highlight for the selected tab.

.iceTabSetTabOn .MiddleTop{
    background-color:#0000FF;
    background-repeat:repeat-x;
    text-align:center;
    padding-top:5px;
    border:none;
}

Other CSS changes were done to help display the possibilities, and since all the relevant classes are accessible the tab style can be completely changed.

Download the demo:

Interaction with the demos has so far been rather static. In the next section the dynamic addition and removal of tabs will be covered.

Dynamically Adding or Removing Tabs

Now we will look at how the iterative support of panelTabSet allows for dynamically adding and removing tabs. From a code point of view this functionality is merely manipulation of the backing bean list. To use the dynamic add / remove code, an iterative panelTabSet must be used, and a simple add and remove method must be added.

For this example, the add method will append a generic tab to the end of the panelTabSet. The code should be similar to the following:

    public void addTab() {
        tabs.add(new Tab("Label " + (tabs.size()+1), "Content " + (tabs.size()+1)));
    }

This will create a new tab with the label and content as the next available integer based on the current number of tabs. With the automatic rendering capabilities of ICEfaces, the page would be updated to display a new tab appended to the end of the ice:panelTabSet.

The remove method for this example is also simple, and deletes the last tab from the panelTabSet. Remember that this could easily be extended to allow the removal of specific tabs, or groups of tabs, etc. Basically anything possible in a list can be performed on the backing bean for a panelTabSet. An example of the simple remove method follows:

    public void removeTab() {
        if (tabs.size() > 0) {
            tabs.remove(tabs.size()-1);
        }
    }

The method ensures that a tab remains to remove, and deletes the last tab in the list. As with addition, the page will automatically update to reflect the fewer tabs.

The screenshot below displays how the dynamic-tabset demo appears initially (before any tabs are added or removed).

Dynamic Panel Tabset Example

This demo uses the same backing bean setup as the basic-tabset demo above. The only difference is the add / remove methods, which can be viewed in the modified TabsetBean.java.

Download the demo:

In summary, the use of a list (either ArrayList or Vector is recommended) and iterative panelTabSet allows for great control over the addition and removal of tabs. In addition to this dynamic functionality, the placement of tabs can also be seemlessly changed, as the next example will demonstrate.

Dynamically Changing Tab Placement

In this next example we are going to dynamically toggle the position of the panelTabSet between the top and bottom. This is achieved by adding a set of radio buttons to the page, which tie into a setPlacement method in the backing bean. The placement is applied as an attribute on the ice:panelTabSet tag, as shown below.

    <ice:panelTabSet tabPlacement="#{tabset.placement}">

The radio buttons have a top and bottom option available, the code for which follows.

    <ice:selectOneRadio value="#{tabset.placement}" partialSubmit="true">
        <f:selectItem itemLabel="Top" itemValue="top"/>
        <f:selectItem itemLabel="Bottom" itemValue="bottom"/>
    </ice:selectOneRadio>

By using partialSubmit="true" in the selectOneRadio tag, the selected option will update the backing bean immediately. This in turn will cause the page to rerender with the tabs displaying at the correct location. The backing bean needs to be changed to have a String placement variable, as well as related getters and setters. These changes can be seen in TabsetBean.java. The following screenshot displays how the tabset-placement demo looks by default.

Placement Panel Tabset Example

Note that the only placement options available are top and bottom.

Download the demo:

Examples Using Panel Tabsets

Example Source Notes
Component Showcase Available in release bundles Panel Tabset example which includes tab visibility, selection, adding and removing, and placement.
Webmail Available in release bundles Tabs are integrated into the settings for a user, allowing form data to be categorized and streamlined.
Acronym Game Available on the demo site The login page uses tabs to seperate the creation and joining of games.
tabset-basic tabset-basic source code Simple example of how to setup a basic panelTabSet component and backing bean.
tabset-style tabset-style source code Demonstration of how easily and fully a panelTabSet can be styled with custom CSS.
tabset-placement tabset-placement source code Example showing the dynamic switching of tab placement.
tabset-dynamic tabset-dynamic source code This example allows the dynamic addition and removal of generic tabs.

The ICEfaces Tutorial
Table of Contents

Copyright 2006 ICEsoft Technologies Inc. All rights reserved.