7 Replies Latest reply on May 29, 2007 6:10 AM by paul kerrison

    rich:tabPanel - dynamic tabs?

    Richard Hardy Newbie

      I have been using ajax4jsf for a while and now that RichFaces has moved to JBOSS, I am looking at using some of the components from it in my project.

      What I would like to know is, is it possible to dynamically add and remove tabs from the rich:tabPanel component?

      What I would like to do, is have a list of links somewhere on the page, and when the user clicks on any of the links, a new tab is added to the tabPanel.

      Ideally, what I would like to do is similar to the following (I am using facelets as well):

      <rich:tabPanel id="tabPane" switchType="ajax">
       <ui:repeat var="oneDoc" value="#{tabManager.managedDocumentsCIDList}">
       <rich:tab label="${tabManager.managedDocuments[oneDoc].editedDocument.CID}"

      However, it seems that the problem is that the rich:tabPanel component will not accept ui:repeat as a child element.

      I had a similar problem when using the Tomahawk tab component, and the only way to fix it was to write a custom renderer.

      Does anyone have any other solutions?

      Thanks in advance,

        • 1. Re: rich:tabPanel - dynamic tabs?
          Sergey Smirnov Master

          I thing the easiest way instead is having a component binding for the rich:tabPanel and creating the tab set there.

          However, using the iteration is an interesting case also. Let's see can we do something is the feature

          • 2. Re: rich:tabPanel - dynamic tabs?
            Richard Hardy Newbie

            Thanks for your help. I have tried a component binding in the past with the Tomahawk tab component and this does, indeed, work. However, the problem is that if you want the tabs to contain complex trees of sub-components, it gets very complicated to generate all of this in java code. It is much nicer, from a design point of view, to do this with facelets.

            Any future development in this area would be very useful for me.


            • 3. Re: rich:tabPanel - dynamic tabs?
              Nick Belaevski Master

              You can put all tabs on the page and then switch off some of them by setting "rendered" to false.

              ui:repeat doesn't work well, because tabPanel is an input and stores current tab state; that's what ui:repeat doesn't allow. c:forEach can be a solution.

              Best regards,

              • 4. Re: rich:tabPanel - dynamic tabs?
                Richard Hardy Newbie

                Thanks for your help. The problem is that I don't know, at design time, how many tabs there are going to be, so I might not allocate enough tabs to begin with (using the rendered=false approach).

                I have seen in other component libraries (e.g. ICEFaces) that tab components have a similar interface to data tables. i.e. <ice:panelTabSet var="currentTab" value="#{tabset.tabs}"> This feature would be really useful for the project that I am working on.

                I have tried the c:forEach approach as well, but this does not seem to update the tab list as part of the Ajax mechanism. When I tried this in the past, it seemed that all worked well as a standard JSF page, but when using Ajax4JSF any tabs that I added during an ajax action were not displayed until I did a full page refresh.


                • 5. Re: rich:tabPanel - dynamic tabs?
                  Sergey Smirnov Master

                  We can add the tabSet to the TODO list, if it is desired.

                  • 6. Re: rich:tabPanel - dynamic tabs?
                    Georges Berscheid Newbie


                    I would love to see dynamic tabs too. I just wonder though how it would be possible to add complex content to the dynamically created tabs. Can I assign a facelets template to a tab so that the contents of that template file are rendered inside the tab?
                    What would be the best strategy to implement this? Any ideas are greatly appreciated.


                    • 7. Re: rich:tabPanel - dynamic tabs?
                      paul kerrison Newbie


                      "SergeySmirnov" wrote:
                      I thing the easiest way instead is having a component binding for the rich:tabPanel and creating the tab set there.

                      Does anyone have an example of how to do this?

                      Presumably, you'd have something like this in th JSP:

                      <rich:tabPanel binding="#{exampleManager.tabPanel}">

                      and then something like this in a manager bean:

                      package jsfTemplate.beans;
                      import java.io.Serializable;
                      import java.util.List;
                      import javax.faces.application.Application;
                      import javax.faces.component.html.HtmlOutputLabel;
                      import javax.faces.context.FacesContext;
                      import org.apache.log4j.Logger;
                      import org.richfaces.component.html.HtmlTab;
                      import org.richfaces.component.html.HtmlTabPanel;
                      import org.richfaces.model.Tab;
                      import org.richfaces.renderkit.TabClassBuilder;
                      import uk.co.tpplc.jsfTemplate.utils.ExampleEnum;
                      public class ExampleManager implements Serializable {
                       private static Logger logger = Logger.getLogger(ExampleManager.class);
                       private static final long serialVersionUID = -8009621080673380811L;
                       private HtmlTabPanel tabPanel;
                       public HtmlTabPanel getTabPanel() {
                       return tabPanel;
                       public void setTabPanel(HtmlTabPanel tabPanel) {
                       this.tabPanel = tabPanel;
                       public void createTabs(){
                       logger.info("Creating tabs");
                       Application application = FacesContext.getCurrentInstance().getApplication();
                       List children = tabPanel.getChildren();
                       HtmlTab newTab = null;
                       for (ExampleEnum label : ExampleEnum.values()){
                       newTab = (HtmlTab)application.createComponent(HtmlTab.COMPONENT_TYPE);
                       logger.info("Child Count: " + tabPanel.getChildCount());

                      But this doesn't work...Has anyone got an example - it's quit ehard to find documentation etc