1

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 Answer 1

2

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
}
Sign up to request clarification or add additional context in comments.

4 Comments

I added the code that builds the tabs. Also this is in view scope.
Thanks a lot that worked great. That was a great idea to bind it to the composite itself.
I am having the same issue with sorting that I had with the command button. The sorting is throwing errors that it can't find a property. It is looking for the property from the class in the tables list of the last datatable built. This error happens when I go between tabs or hit a command button. Is there a way to bind the sorting to the composite itself. Not sure how to fix this.
Thanks for the answer. The second solution is really nice.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.