I'm having trouble making a dataTable where each row has a inputText and a commandLink. When the link is clicked, only it's row's inputText's data is submitted.
Something like this?
<h:dataTable value="#{bean.items}" var="item">
<h:column>
<h:inputText value="#{bean.value}"/>
</h:column>
<h:column>
<h:commandLink action="#{bean.save}" value="save">
<f:setPropertyActionListener target="#{bean.item}" value="#{item}" />
</h:commandLink>
</h:column>
</h:dataTable>
Bean:
@RequestScoped
public class Bean {
private Item item;
private String value;
Right now, as it is, it's using the last row's inputText
to fill the value
. I wrapped another h:form
, but it broke other things and I've learned that nested h:form
is not the right way to do it hehe
What's the correct way to do this?
Thanks.
You're binding the value of all HTML input elements to one and same bean property. This is of course not going to work if all those HTML input elements are inside the same form. All values are subsequently set on the very same property in the order as the inputs appeared in the form. That's why you end up with the last value. You'd like to move that form to inside the
<h:column>
(move; thus don't add/nest another one).The usual approach, however, would be to just bind the input field to the iterated object.
An alternative, if you really need to have your form around the table, is to have a
Map<K, V>
as bean property whereK
represents the type of the unique identifier of the object behind#{item}
andV
represents the type ofvalue
. Let's assume that it'sLong
andString
:with
This way you can get it in the action method as follows:
By the way, if you happen to target Servlet 3.0 containers which supports EL 2.2 (Tomcat 7, Glassfish 3, etc), then you can also just pass the
#{req}
as a method argument without the need for a<f:setPropertyActionListener>
.See also: