Dynamically creating RichFaces tabs

I saw a reference (http://mkblog.exadel.com/?p=115) to my blog on one of the Brazilian JSF forums. I translated the thread using Google and it looked like someone was asking how to create RichFaces tabs dynamically. So, here is quick example.

XHTML page:




RichFaces



   
     
       
       
          
	      
       
       
      
   



Managed bean:

package tabs;

import javax.faces.application.Application;
import javax.faces.component.html.HtmlPanelGrid;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import org.richfaces.component.html.HtmlTab;
import org.richfaces.component.html.HtmlTabPanel;

public class TabsBean {

   private HtmlPanelGrid panelGrid;
   private Integer numOfTabs;

   public Integer getNumOfTabs() {
	return numOfTabs;
   }
   public void setNumOfTabs(Integer numOfTabs) {
	this.numOfTabs = numOfTabs;
   }
   public TabsBean() {
   }
   public HtmlPanelGrid getPanelGrid() {
	return panelGrid;
   }
   public void setPanelGrid(HtmlPanelGrid panelGrid) {
	this.panelGrid = panelGrid;
   }
   public void createTabs (ActionEvent event){
	FacesContext context = FacesContext.getCurrentInstance();
	Application application = context.getApplication();
	HtmlTabPanel tabPanel = (HtmlTabPanel)application.createComponent(HtmlTabPanel.COMPONENT_TYPE);
	tabPanel.setSwitchType("ajax");

	for (int i=0; i<numOfTabs; i++){
		HtmlTab tab = (HtmlTab)application.createComponent(HtmlTab.COMPONENT_TYPE);
		tab.setLabel("Nice Tab # "+(i+1));
		tab.setName(i);
                tabPanel.getChildren().add(tab);
	}

	panelGrid.getChildren().clear();
	panelGrid.getChildren().add(tabPanel);
   }
}

You will get this:

tabs1.png

tabs2.png

30 thoughts on “Dynamically creating RichFaces tabs

  1. hey max

    I created a project to test this example, but have some errors. And my environment: eclipse 3.3.x; ant1.7.0; jboss4.2.3GA and jboss-seam-2.1.0. I think the errors should be the environment or config issues. Can you tell me your detail config? thank you a lot.

    Stack Trace:
    Exception during request processing:
    Caused by javax.servlet.ServletException with message: “/layout/func-template.xhtml @44,64 actionListener=”#{tabsBean.createTabs}”: java.lang.ClassCastException: org.richfaces.component.html.HtmlTabPanel cannot be cast to org.richfaces.component.html.HtmlTabPanel”
    javax.faces.webapp.FacesServlet.service(FacesServlet.java:277)
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)
    org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:38)
    org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
    org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:90)
    org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
    org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64)
    org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
    org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
    org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
    org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:150)
    org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:267)
    org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:379)
    org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:506)
    org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:56)
    org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
    org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:58)
    org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
    org.jboss.seam.debug.hot.HotDeployFilter.doFilter(HotDeployFilter.java:44)
    org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
    org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
    org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:182)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:432)
    org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
    org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
    org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:262)
    org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
    org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
    org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:446)
    java.lang.Thread.run(Unknown Source)

  2. Thanks for your answer, and I have replaced all richfaces jars with the richfaces3.2.2.SR1, but the error still exists. Do I need to modify any config files?

  3. Hello Max,

    I’m trying to add dynamic content to each new tab by using an include.
    however I’m not successful.

    here is what I do:

    Include includeTag = new Include();

    includeTag.setId(“inc” this.count );
    includeTag.setViewId(“snippet.xhtml”);

    tab.setId(“newtab” this.count );
    tab.getChildren().add(includeTag);

    tabPanel.getChildren().add(tab);
    tabPanel.setSelectedTab(“newtab” this.count );

    the tab is being added but no content inside.

    Please help,
    Thank you very much,
    Yaniv.

  4. It’s not possible to add a4j:include dynamically right now. The component is added to the tree but the subtree (that actual include) is not processed.

  5. One option is to do this, although, you will need to know how many tabs you have ahead of time:

    ...
    
    ...
    

    Another option is to try using ui:include instead of a4j:include with includeFacelet(..) method:

    public void apply(FaceletContext ctx, UIComponent parent)
       throws IOException, FacesException, FaceletException, ELException {
       String path = this.src.getValue(ctx);
       VariableMapper orig = ctx.getVariableMapper();
       ctx.setVariableMapper(new VariableMapperWrapper(orig));
       try {
          this.nextHandler.apply(ctx, null);
          ctx.includeFacelet(parent, path);
        } finally {
           ctx.setVariableMapper(orig);
        }
    }
    

    I haven’t tried, if you try it, let me know if it works.

  6. Hello again Max,

    I tried to follow up on your suggestion but I’m really not an expert.

    From what I have understood, I tried writing a tag handler and adding that to the tab. however the tab wont accept taghandlers only UIcomponents.

    Is there a way to make the include processed?

    I would really appreciate your help on this issue.
    A full code example would be even more appreciated 🙂

    Thank you very much in advance,
    Yaniv.

  7. Insert title here

    I am new to fiji charts… but i am using jsf richfaces…
    pls help i am gettting error like this..
    java.lang.ClassCastException: org.ajax4jsf.component.AjaxViewRoot cannot be cast to com.exadel.fiji.component.html.HtmlBarChart

  8. Hi
    I tried your example but getting an error.

    Strack Trace:
    java.lang.NullPointerException
    at org.richfaces.renderkit.TabPanelRendererBase.encodeTabs(TabPanelRendererBase.java:354)
    at org.richfaces.renderkit.html.TabPanelRenderer.doEncodeBegin(TabPanelRenderer.java:248)
    at org.richfaces.renderkit.html.TabPanelRenderer.doEncodeBegin(TabPanelRenderer.java:200)
    at org.ajax4jsf.renderkit.RendererBase.encodeBegin(RendererBase.java:101)
    at javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:788)
    at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:269)
    at com.sun.faces.renderkit.html_basic.GroupRenderer.encodeChildren(GroupRenderer.java:117)
    at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:812)
    at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:271)
    at com.sun.faces.renderkit.html_basic.GridRenderer.encodeChildren(GridRenderer.java:242)
    at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:812)
    at org.ajax4jsf.renderkit.RendererBase.renderChild(RendererBase.java:282)
    at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxComponent(AjaxChildrenRenderer.java:124)
    at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxChildren(AjaxChildrenRenderer.java:67)
    at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxComponent(AjaxChildrenRenderer.java:115)
    at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxChildren(AjaxChildrenRenderer.java:67)
    at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxComponent(AjaxChildrenRenderer.java:115)
    at org.ajax4jsf.renderkit.AjaxContainerRenderer.encodeAjax(AjaxContainerRenderer.java:123)
    at org.ajax4jsf.component.AjaxViewRoot.encodeAjax(AjaxViewRoot.java:677)
    at org.ajax4jsf.component.AjaxViewRoot.encodeChildren(AjaxViewRoot.java:548)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:886)
    at com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.java:592)
    at org.ajax4jsf.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:100)
    at org.ajax4jsf.application.AjaxViewHandler.renderView(AjaxViewHandler.java:176)
    at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:106)
    at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:251)
    at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:144)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:245)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:178)
    at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
    at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:390)
    at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:517)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
    at java.lang.Thread.run(Thread.java:619)

    Your help greatly appreciated. Thank you.

  9. Sorry. I want to use the intialisation of tabs in encodeBegin method, can we do that??i tried putting the code of cretaeTabs methos in encodeBegin method but it doesnt work.can we initialise the richfaces tabs
    in the start up?

  10. max, the encodeBegin method of the Renderer Class where we have the ResponseWriter to generate the code.We already have a tabed system using a pure html one but want to use richfaces tabs in this method.

    public void encodeBegin(FacesContext context, UIComponent component) throws IOException { }

  11. MAX, I have tried several ways but couldnt.looks like encodeBegin allows only pure html based components to be rendered.

  12. Hi Max,

    I have a requirement like need to display more tabs in a single page, since there are more, I kept horizontal scroll bar, but I do not want it. I want an arrow indicating more tabs ahead like how firefox,chrome or IE tabbed browsers behave.

    How can achieve this for rich tabs.

  13. hi,
    i Create tabpanel dynamically with the class “org.richfaces.component.html.HtmlTabPanel”
    i add for my tabpanel liste of tab it work well
    but my problem i want to add for each tab a datatable !!:(
    i obtain the message in my browser ” org.richfaces.component.html.HtmlTabPanel cannot be cast to org.richfaces.component.html.HtmlDataTable”
    how i can add datattable for ech tab

  14. Is there an alternative to this solution you’ve presented here? I’m asking this because of the current ViewScoped bug in mojarra where a viewscoped bean behaves like a request scoped bean when any component is bound to it. Primefaces offers dynamic component generation out of the box but i’m more comfortable with richfaces. Is there any way aroud this? Thx

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s