Wicket - Datatable custom pagination

394 Views Asked by At

I am working on wicket datatable which uses built-in pagination feature where data is given through dataprovider. Wicket NavigationToolbar for displays links used to navigate the pages of the datatable as shown below

public class AbstractDataTable<T, S> extends DataTable<T, S> {
    private static final long serialVersionUID = -3370089530205846951L;

    public AbstractDataTable(String id, List<? extends IColumn<T, S>> columns, ISortableDataProvider<T, S> dataProvider) {
        this(id, columns, dataProvider, DataTableConstants.DEFAULT_ELEMS_PER_PAGE);
    }

    public AbstractDataTable(String id, List<? extends IColumn<T, S>> columns, ISortableDataProvider<T, S> dataProvider,
            int elemsPerPage) {
        super(id, columns, dataProvider, elemsPerPage);      
        addToolbars(dataProvider);
    }
    
    protected void addToolbars(ISortableDataProvider<T, S> dataProvider) {
        addTopToolbar(new HeadersToolbar<S>(this, dataProvider));
        addBottomToolbar(new NavigationToolbar(this));
        addBottomToolbar(new NoRecordsToolbar(this));
    }   

Here dataprovider holds entire data to be displayed so it takes too long time get entire data from database. So, to avoid that i am planning to implement pagination in such a way that to call database every time on clicking next button according to pagesize. Basically like below

select * from table_name LIMIT 25 OFFSET ${req.query.pageNumber25} will limit the number of records to 25. when req.query.pageNumber=1, it will offset first 25records and sends next 25 records. similarly if req.query.pageNumber=2, it will offset first 225 records and sends 51-75 records.

Got stuck here where i am looking ways to implement above feature

Update

Skeleton of dataprovider

public class DataTableProvider<T extends AbstractDataProvider> extends  BaseProvider implements Serializable {

    private static final long serialVersionUID = -6593326956377071200L;

    private final List<T> searchResults;

    public DataTableProvider() {
        this(null);
    }

    public DataTableProvider(List<T> bo) {
        this.searchResults = null != bo ? bo : new LinkedList<T>();
    }

    public List<T> provide() {
        return searchResults;
    }

    public int size() {
        return provide().size();
    }

    public void update(List<T> bos) {
        searchResults.clear();
        searchResults.addAll(null != bos ? bos : Collections.<T> emptyList());
    }

    public boolean isEmpty() {
        return provide().isEmpty();
    }
}

Above dataprovider is populate on clicking the search button

    @Override
    protected void onSubmit(SearchFilterBO criteria) {
        if (getLog().isDebugEnabled()) {
            getLog().debug(format(MSG_PTRN_SEARCH_SUBMISSION, ToStringBuilder.reflectionToString(criteria)));
        }
        getResultsProvider().update(searchService.searchBy(criteria));
        getLog().info(format(MSG_PTRN_SEARCH_ENDED, getResultsProvider().size()));
    }
1

There are 1 best solutions below

0
A.Alexander On

Your implementation of data provider is incorrect. You have to override 'iterator' method of IDataProvider and select your data there. Also BaseProvider is not presented in wicket libs. Here is a simple example:

IDataProvider<Location> provider = new IDataProvider<>() {
        @Override
        public Iterator<? extends Location> iterator(long first, long count) { 
            return getLocationDAO().findAll(first, count).iterator();
        }

        @Override
        public long size() {
            return getLocationDAO().getTotal();
        }

        @Override
        public IModel<Location> model(Location object) {
            return new Model<>(object);
        }
    };