Reputation: 10372
I have a dataTable. The data of the dataTable is filled via ajax. A row of the table contains among other things form elements like a button. The button in the datatTable should refer to another page but if I click on them the current page is reloaded.
Here some code:
the backing bean:
@ManagedBean(name="bean")
@SessionScoped
public class Bean {
private List<String> data;
@PostConstruct
public void postConstruct() {
data = new ArrayList<String>();
}
public void fillTable() {
data.add("E1");
data.add("E2");
data.add("E3");
}
public String outcome(){
return "/faces/test/edit.jsf";
}
public List<String> getData() {
return data;
}
public void setData(List<String> data) {
this.data = data;
}
}
the page:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org /TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html" >
<h:body>
<h:form id="form">
<h:commandButton value="fillTable">
<f:ajax listener="#{bean.fillTable()}" render="@form"/>
</h:commandButton>
<h:dataTable id="table" var="data" value="#{bean.data}">
<h:column>
<h:outputText value="#{data}" />
</h:column>
<h:column>
<h:commandButton value="edit" action="#{bean.outcome}" />
</h:column>
</h:dataTable>
</h:form>
</h:body>
</html>
I know that this has something to do that the form is already in the dom and the button are lazy loaded into the page (if someone could be more specific I would be very pleased).
Although if I change the Scope of the backing bean to SessionScope it works. The button redirect to the right page. Why?
Upvotes: 1
Views: 805
Reputation: 1108792
Although if I change the Scope of the backing bean to SessionScope it works. The button redirect to the right page
The bean should have been placed in the view scope. The session scope is too broad and would only risk unintuitive behaviour when the same view is been opened in multiple browser windows/tabs in the same session.
The explanation is as follows: when a form is submitted, JSF needs to identify the command button pressed in order to invoke the associated action method. As the command button is been placed in side a datatable, JSF needs to iterate over its datamodel first. But if the datamodel has been changed, or is empty, then JSF won't be able to identify the command button. Hence the action won't be invoked.
When the bean is in the request scope, then it will be trashed by end of response and recreated during every new request, including ajax requests. All of the bean's properties will obviously get the default values again, so also the data
property in your case.
Upvotes: 4