I am trying to execute an action
through commandButton
inside a dataTable
, but the action
is not invoked when the commandButton
is placed inside the datatable as shown below
<h:form>
<h:dataTable value="#{bean.list}" var="item">
<h:column>
<h:commandButton value="submit" action="#{bean.submit}" />
</h:column>
</h:dataTable>
</h:form>
When I move the commandButton
out of dataTable
, the action
is successfully executed. What is the problem when commandButton
is inside datatable? The commandLink
has the same problem.
This problem can happen when the list behind #{bean.list}
is not exactly the same during the HTTP request of processing the form submit as it was during the request of displaying the form. JSF will namely re-iterate over the list to locate the button pressed and invoke its action.
If the bean is request scoped and the list is not repopulated during bean's (post)construction, or the list's population depends on a request scoped variable which was lost during the form submit, then JSF will retrieve an empty or a completely different list while processing the form submit and thus won't be able to locate the button pressed and won't invoke any action.
The best fix is to put the bean in the view scope and ensuring that you're loading the data model the proper way.
@ManagedBean
@ViewScoped
public class Bean implements Serializable {
private List<Item> list;
@EJB
private ItemService service;
@PostConstruct
public void init() {
list = service.list();
}
// ...
}
See also:
- commandButton/commandLink/ajax action/listener method not invoked or input value not updated - point 4
- Benefits and pitfalls of
@ViewScoped