1
votes

I have a JSF page that dynamically builds tabs. In each tab there are some input fields and a command button. The fields and buttons are dynamically built when the tabs are built. When I add a binding attribute to the command button, only one button in one tab is generated. There should be a command button in every tab. When I remove the binding attribute all the buttons are there but no required validation occurs. How can I add a unique binding value for each command button created in the loop.

All of the below code is inside a loop that generates tabs in a tab view.

    <ui:repeat value="#{cc.attrs.dataTableTemplate.columns}" var="column">
        <p:outputLabel styleClass="outputLabel" value="#{column.heading}" 
            for="inputtext" rendered="#{column.editable}"/>
        <p:inputText value="#{cc.attrs.dataTableTemplate.collectorValue[column.name]}" 
            rendered="#{column.editable}"
            id="inputtext" required="#{not empty param[add.clientId]}"/>
        <div class="clear">&#160;</div>
    </ui:repeat>
    <p:commandButton styleClass="commandButton"
         binding="#{add}"
         value="add"
         update="pnl_codetable @parent"
         title="Add">
        <p:collector value="#{cc.attrs.dataTableTemplate.collectorValue}" 
           addTo="#{cc.attrs.pageBean.getDataTableList(
           cc.attrs.dataTableTemplate.tableListName)}" />
    </p:commandButton>

Here is the code that creates the tabs and calls the above code with the maintenence_code tag.

    <p:accordionPanel id="pnl_accord_codetables" dynamic="true" cache="false">
         <p:ajax event="tabChange" listener="#{pc_Maintenence.onTabChange}"/>
         <c:forEach items="#{pc_Maintenence.codeMaintenenceTables}" var="codetable">    
             <p:tab title="#{codetable.tableName}">
                 <util:maintenence_code pageBean="#{pc_Maintenence}" dataTableTemplate="#{codetable}"/>
            </p:tab>
        </c:forEach>
   </p:accordionPanel>
1

1 Answers

2
votes

The binding attribute is basically view scoped. You can't bind physically multiple components in the same view to one and same view scoped variable. It can refer only one component. In your case, basically every component is overriding each other during setting that attribute so that you end up seeing only one, which is the last one.

You're not clear on how you're creating tabs, but you should in some way include the tab identifier in the variable used in the binding attribute. Perhaps something like this?

faces-config.xml:

<managed-bean>
    <managed-bean-name>components</managed-bean-name>
    <managed-bean-class>java.util.HashMap</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>

View:

<c:set var="buttonId" value="add_#{someTabId}" />
...
<p:inputText ... required="#{not empty param[components[buttonId].clientId]}" />
...
<p:commandButton binding="#{components[buttonId]}" ... />

Update, wait it's a composite, another way would be to just bind it to the composite itself

<cc:interface componentType="myComposite">
...
<p:inputText ... required="#{not empty param[cc.add.clientId]}" />
...
<p:commandButton binding="#{cc.add}" ... />

with

@FacesComponent("myComposite")
public class MyComposite extends UINamingContainer {

    private UICommand add; 

    // +getter +setter
}