Reputation: 96
In Primefaces 2.2 , if you want to get DataTable selection, you need to commit the datatable without validation failed or converter failed.
Like below:
<p:dataTable update="outputPanel" id="dataTable" var="car"
value="#{tableBean.cars}" selection="#{tableBean.selectedCars}">
<p:column selectionMode="multiple" />
<p:column style="width:200px" id="Model">
<f:facet name="header">
Model
</f:facet>
<h:outputText value="#{car.model}" />
<h:inputText value="#{car.model}" >
<f:attribute name="datatableClientId" value="form:dataTable" />
<f:attribute name="datatable" value="#{dataTableBinding}" />
<f:validator validatorId="dataTableRequiredValidator" />
</h:inputText>
</p:column>
</p:dataTable>
When the validator is falied, how to get the selectedCars in the validator?
Upvotes: 1
Views: 1469
Reputation: 96
I look into the Primefaces 2.2 source code , when decode a datatable will use the DataHelper class to decodeSelection. So I copy the code to write a util class ,like below:
//when the validator in a row, the datatable clientId will be wrong append the row number. so please specify the table clientId.
public Object getDataTableSelection(FacesContext context, DataTable table, String dataTableclientId) {
String clientId = dataTableclientId != null ? dataTableclientId : table.getClientId(context);
Map<String, String> params = context.getExternalContext().getRequestParameterMap();
String selection = params.get(clientId + "_selection");
Object data = null;
if (table.isSingleSelectionMode()) {
data = decodeSingleSelection(table, selection);
} else {
data = decodeMultipleSelection(table, selection);
}
table.setRowIndex(-1); // clean
return data;
}
private Object decodeSingleSelection(DataTable table, String selection) {
Object data = null;
if (isValueBlank(selection)) {
table.setSelection(null);
table.setEmptySelected(true);
} else {
int selectedRowIndex = Integer.parseInt(selection);
int first = table.getFirst();
int rows = table.getRows();
int last = rows == 0 ? table.getRowCount() : rows;
if (first <= selectedRowIndex && (first + last) > selectedRowIndex) {
table.setRowIndex(selectedRowIndex);
data = table.getRowData();
table.setSelection(table.getRowData());
}
}
return data;
}
private boolean isValueBlank(String value) {
if (value == null)
return true;
return value.trim().equals("");
}
private Object decodeMultipleSelection(DataTable table, String selection) {
Class<?> clazz =
table.getValueExpression("selection").getType(FacesContext.getCurrentInstance().getELContext());
Object data = null;
if (isValueBlank(selection)) {
data = Array.newInstance(clazz.getComponentType(), 0);
table.setSelection(data);
} else {
if (!table.isCellSelection()) {
String[] rowSelectValues = selection.split(",");
data = Array.newInstance(clazz.getComponentType(), rowSelectValues.length);
for (int i = 0; i < rowSelectValues.length; i++) {
table.setRowIndex(Integer.parseInt(rowSelectValues[i]));
Array.set(data, i, table.getRowData());
}
table.setSelection(data);
}
}
return data;
}
So you can use the getDataTableSelection(current facescontext instance, datatable instance, table clientId)
method to get the selection.It will return a array object(never be null).
Note: when the validator in a row, the datatable clientId will be wrong append the row number. so please specify the table clientId.
Upvotes: 1