Search code examples
jsfjsf-2icefaces

How dynamically generate ace:tabPane components?


I am using JSF 2.1 and ICEFaces 2 and I have a tabset like:

<ace:tabSet clientSide="true">
    <ace:tabPane>
        <f:facet name="label">My First Tab</f:facet>
        <h:outputText value="One"></h:outputText>
    </ace:tabPane>
    <ace:tabPane>
        <f:facet name="label">Second Tab</f:facet>
        <h:outputText value="Two"></h:outputText>
    </ace:tabPane>
    <ace:tabPane>
        <f:facet name="label">Third Tab</f:facet>
        <h:outputText value="Third"></h:outputText>
    </ace:tabPane>
</ace:tabSet>

Instead of hardcoding the tabPanes, I want to generate them dynamically based on a list. How can I achieve this by standard JSF or ICEFaces components?

I tried to use the <ui:repeat>, but it doesn't work:

<ui:repeat var="o" value="#{bean.myList}" varStatus="status">
    <ace:tabPane>
        <f:facet name="label">#{o.name}</f:facet>
        <h:selectManyCheckbox value="#{o.valuesArray}" layout="pageDirection">
            <f:selectItems value="#{o.checkboxes}" />
        </h:selectManyCheckbox>
    </ace:tabPane>
</ui:repeat>

Solution

  • I don't do ICEFaces, but you're encountering basically the same problem as RichFaces has with its <rich:tab>. As there exist no hypothetical <rich:tabs> (like as <rich:columns> which would be the dynamic variant of <rich:column>/<h:column>), one would have to use the view build time JSTL <c:forEach> tag to prepare the JSF view with those tags. You could apply the same on your ICEFaces page:

    <ace:tabSet clientSide="true">
      <c:forEach items="#{bean.tabs}" var="tab">
        <ace:tabPane>
          <f:facet name="label">#{tab.label}</f:facet>
          <h:outputText value="#{tab.name}"></h:outputText>
        </ace:tabPane>
      </c:forEach>
    </ace:tabSet>
    

    Note that this will only fail if #{bean} is not a real managed bean, but an expression which in turn depends on an evaluation of another JSF component, such as <h:dataTable var="bean">.

    The <ui:repeat> won't work as it's a render-time tag. It won't dynamically generate multiple JSF components before the JSF component tree is been built.

    See also: