While deleting rows from an iterating component like a <p:dataTable>
, the current page needs to be reset to its immediate previous page, if all of the rows in the last page have been deleted. This is unfortunately not automated in <p:dataTable>
with LazyDataModel<T>
.
Linguistically, if a data table contains 11 pages with 10 rows per page and all of the rows on the 11th page i.e the last one are deleted, it should get the 10th page automatically (i.e. the immediate previous page) but this does not happen automatically (the current page remains stationary (11th) as if the data table itself gets emptied) unless explicitly coded somewhere in the associated backing bean.
Informally, the corresponding pseudo code segment would look something like the following.
if (rowCount <= (ceiling)((first + 1) / pageSize) * pageSize - pageSize) {
first -= pageSize;
}
Where first
is the page offset (starting with 0
), pageSize
indicates rows per page and rowCount
indicates the total number of rows from the associated data-store/database.
Practically :
@Override
public List<Entity> load(int first, int pageSize, List<SortMeta> multiSortMeta, Map<String, Object> filters) {
// ...
int rowCount = service.getRowCount();
setRowCount(rowCount);
// ...
if (pageSize <= 0) {
// Add an appropriate FacesMessage.
return new ArrayList<Entity>();
} else if (first >= pageSize && rowCount <= Utility.currentPage(first, pageSize) * pageSize - pageSize) {
first -= pageSize;
} else if (...) {
// ...
}
// ...
return service.getList(first, pageSize, map, filters);
// SortMeta in List<SortMeta> is PrimeFaces specific.
// Thus, in order to avoid the PrimeFaces dependency on the service layer,
// List<SortMeta> has been turned into a LinkedHashMap<String, String>()
// - the second last parameter (named "map") of the above method call.
}
The static utility method Utility#currentPage()
is defined as follows.
public static int currentPage(int first, int pageSize) {
return first <= 0 || pageSize <= 0 ? 1 : new BigDecimal(first + 1).divide(new BigDecimal(pageSize), 0, BigDecimal.ROUND_CEILING).intValue();
}
This is a piece of boilerplate code and should be avoided being repeated all over the place - in every managed bean using a <p:dataTable>
with LazyDataModel<T>
.
Is there a way to automate this process?