'PrimeFaces DataTable - selection in view set to null when submitting form and table itself not in form
edit: Based on Jasper's comment, the selection feature requires p:dataTable to be in a form, so my question is moot.
I have a DataTable outside of a form. When I submit the form (non-ajax), the field referenced by the selection attribute is set to null in my view. This happens for PrimeFaces 10.0.1 and higher. In 10.0.0 and 8.x, the field is not touched.
The field in the example is DtView.selectedEntry.
xhtml:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:p="http://primefaces.org/ui"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<title>PrimeFaces Test</title>
</h:head>
<h:body>
<p:dataTable id="data-table" var="entry"
value="#{dtView.entries}"
rowKey="#{entry.id}"
selection="#{dtView.selectedEntry}"
selectionMode="single">
<p:column headerText="Entry">
<h:outputText value="#{entry}" />
</p:column>
</p:dataTable>
<h:form id="frmTest">
<div>
<p:outputLabel for="@next" value="Selected: "/>
<h:outputText id="selected-entry" value="#{dtView.selectedEntry}" />
</div>
<div>
<p:commandButton value="save input"
ajax="false"
imediate="true"
update="@form :data-table"
action="#{dtView.submit()}" />
</div>
</h:form>
</h:body>
</html>
View:
@Data
@Named
@ViewScoped
public class DtView implements Serializable {
private List<Product> entries;
private Product selectedEntry;
@PostConstruct
void setup() {
entries = List.of(
new Product(1, "entry 1"),
new Product(2, "entry 2"),
new Product(3, "entry 3")
);
selectedEntry = entries.get(0);
}
public String submit() {
System.out.println("Selected entry: " + selectedEntry);
return null;
}
}
Console (PrimeFaces 11.0.0 and then 10.0.0):
Selected entry: null
Selected entry: Product(id=1, name=entry 1)
To avoid the 'null' I can put p:dataTable inside a form, so it won't get processed during the apply request value phase or use ajax on the command button. I am not sure why the dataTable is outside a form in my real application to begin with.
I expected a value outside of a form not to be set in the view, but dataTable does not seem to follow this. Is the new PF behaviour more logical and my understanding is wrong?
The reason for this change seems to be located in SelectionFeature.
PF 8: just calls table.setSelection(null);:
https://github.com/primefaces/primefaces/blob/cd4fbdf1d9d4ae054da19b9a84001d0c34d142eb/src/main/java/org/primefaces/component/datatable/feature/SelectionFeature.java#L78
PF 10.0.0: decodeSingleSelection() does not call setSelection() because !rowKeys.isEmpty() evaluates to false (empty check disappears in 10.0.1):
https://github.com/primefaces/primefaces/blob/10.0.0/src/main/java/org/primefaces/component/datatable/feature/SelectionFeature.java#L84
11.0.0: decodeSingleSelection() eventually calls setSelection() to set the value in the view to null:
https://github.com/primefaces/primefaces/blob/11.0.0/primefaces/src/main/java/org/primefaces/component/datatable/feature/SelectionFeature.java#L87
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
