I have a JSF2 application and a page with the following code:
<h:inputText id="someInput" required="true" />
<p:outputPanel id="itemsPanel">
<ui:repeat var="i" value="#{myBean.itemIndices}" id="items">
<h:inputText
id="itemInput"
value="#{myBean.dataItems[i]}"
/>
<h:panelGroup
layout="block"
styleClass="clear"
rendered="#{((i+1) % 10 == 0)}"
/>
</ui:repeat>
</p:outputPanel>
<br/>
<p:commandButton
classStyle="btn"
value="Add Row"
actionListener="#{myBean.increaseItemsCount}"
update="itemsPanel"
immediate="false"
ajax="true"
/>
The ui:repeat is dynamically rendering a number if text boxes depending on the itemIndices and dataItems properties. The “Add Row” button calls a method that will dynamically increase the number of itemIndices and dataItems, therefore additional text inputs appear.
The current code will not work if there is no value in the text box someInput, because the AJAX request also validates the form and validation fails. Pressing the button in this case has no visual effect, not even feedback for the user that validation did not pass (because I update itemsPanel only).
If I change the button to have immediate="true", then the validation issue is no more. Unfortunately, I want to be able to restore the values of the dynamic input fields that the user might have changed prior adding the new row. The immediate="true" attribute causes the form not to be submitted to the server, therefore the user-entered data will not be persisted.
A possible solution to this could be to add process="all dynamic input ids csv" attribute to the command button and set the immediate attribute back to true. This will cause the server to validate only the inputs specified in the process attribute and they will be persisted. The problem here is that these input ids are dynamically generated by JSF and I cannot come up with a proper way to get them as a CSV. I would also not prefer a solution for dynamically generating ids in myBean relying on assumptions of how JSF would output them.
All suggestions will be greatly appreciated.
You could use
process="itemsPanel".You should only move the command button into
<h:outputPanel id="itemsPanel">.