I'm trying to figure out how to do true pagination with richfaces datascroller.
Currently my query pulls all of the data from a table and i want it so when you click the next button of the datascroller, it will query the db for the next 20 rows.
I understand how to write the query to limit the rows, but i'm not sure how to get the datascroller's next button to call a specific method.
I see there are many people posting on the Richfaces forums with potential solutions, but they all use a dataModel. Since i'm not using an ORM, i'm not sure how i can fit these solutions to what i have.
Any help is appreciated.
<rich:extendedDataTable id="resultsTable" value="#{tableBacking.results}" var="results" sortMode="single" rowKeyVar="row">
<rich:columns value="#{tableBacking.columns == null ? '' : tableBacking.columns}" var="columns" index="ind" id="column#{ind}" sortBy="#{results[ind].data}" rendered="#{tableBacking.columns != null}">
<f:facet name="header">
<h:outputText value="#{columns.columnDescription}" />
</f:facet>
<h:outputText value="#{results[ind].data}" />
</rich:columns>
</rich:extendedDataTable>
<rich:datascroller for="resultsTable" page="#{tableBacking.page}" renderIfSinglePage="false" />
Backing bean
public class TableBacking {
private List<List<TableData>> results = null;
private int page = 0;
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public List<List<TableData>> getResults() throws Exception {
return results;
}
public void setResults(List<List<TableData>> results) {
this.results = results;
}
private void getData(String whereClause) {
try {
DataDao dd = new DataDao();
results = dd.getData(); // dd.getData just runs a query on a table and puts the results in a List of lists.
} catch (Exception e) {}
}
Try to do this :
JSF Stuff:
<rich:dataTable id="listTable" var="record" rows="10" value="#{personBean.data}">
....
<f:facet name="footer">
<rich:column colspan="8">
<rich:dataScroller page="#{personBean.page}" for="listTable"
scrollListener="#{personBean.scrollPage}" render="listTable" />
</rich:column>
Records : #{personBean.data.size()}
</f:facet>
</rich:dataTable>
Java BackBean Stuff:
public class PersonBean {
// List of Persons
private PagedList<Person> data;
// Current page
private Integer page;
// Default rows to display
private Integer rows = 10;
// Persistence layer
private DaoService daoService;
@PostConstruct
public void init(){
page= 1;
}
// Event trigger on scroll page
public void scrollPage(DataScrollEvent ev) {
log.debug("Scroll event");
reset();
// getPersons execute 2 queries : the first query is the count(*) and the result is set in TotalElements
// the second query gets the 'n' records defined in rows , something like this :
// select * from Persons LIMIT page*rows, (page*rows) + rows and the result is set in Content
Page<Person> pageResult = this.daoService.getPersons(filter, page - 1, rows);
// Now create a pagedList with the constructor
this.data = new PagedList<Person>(pageResult.getContent(), (int) pageResult.getTotalElements(), this.pageSize);
}
}
Java PagedList
public final class PagedList<E> extends AbstractList<E> {
private final List<E> lista;
private final int total;
private final int pageSize;
public PagedList(List<E> lista, int total, int pageSize) {
this.lista = lista;
this.total = total;
this.pageSize = pageSize;
}
public int size() {
return total;
}
public E get(int i) {
i = i % this.pageSize;
return lista.get(i);
}
}
The trick is to set the total property of PagedList
class with the count of the dataTable
in the database and only set the paged elements in the list of PageList
.
Sorry for my bad english :P