I'm implementing a typical shopping cart, based on PrimeFaces' dataGrid component. Below is some sample code.
Everything is ok, but the inputText field causes the bean property to be set as many times as there are elements in the page. So, if I put 1
in the first item in the datagrid, it is set, but it's set to 0
N times after this, thus overwriting it.
I guess this is because each inputText has the same id. I have tried to enclose the input + commandLink within their own form, but that doesn't work. I am sure this is a common case, and there must be an elegant solution.
<h:form id="itemsForm" prependId="false">
<p:dataGrid id="itemList" value="#{itemsBean.items}" var="item" type="unordered" paginator="true" rows="12" columns="1">
<p:column>
<p:inputText value="#{cartBean.quantity}"/>
<p:commandLink actionListener="#{cartBean.add}" update=":cartPanel" value="Add to cart">
<f:setPropertyActionListener target="#{cartBean.itemToCart}" value="#{item}"/>
</p:commandLink>
</p:column>
</p:dataGrid>
</h:form>
You can use AJAX here to do a
partial submit
* of your form data. I'll give an example here using JSF 2.0's build-in AJAX support and with the standarddataTable
, but the idea is the same for JSF 1.x (using e.g. a4j) anddataGrid
:Facelet:
Bean:
What happens here is that the
<f:ajax>
tag applies Ajax capabilities to the command button. Via theexecute
attribute you tell it that only the input of the component with IDinput
should be processed.In the context of rendering each command button, ID
input
resolves to a different actualclient ID
for each row. E.g.form:table:0:input
for the first row,form:table:1:input
for the second row and so on. Via this, the partial submit is being done and your backing bean's single value binding will receive the value for the row on which the user clicked.Note that in the example given, the table is not re-rendered and the value will 'stick' in each input text component. This might give the illusion your backing bean is bound to multiple values, but this is not the case.
(*) Although conceptually we're talking about a
partial submit
, a specific implementation of JSF (e.g. Mojarra) can still opt to post the whole form and filter it server-side.