Maciej Miklas
Maciej Miklas

Reputation: 3330

Looking for Wicket repeater that works only with iterator (without knowing exact result size)

I am trying to use wicket to display results from nosql database. This means large data sets with unknown size.

I need kind of GridView with paging functionality which DataProvider relies only on iterator and estimated result size (like 100+, which could also mean 500k). Good example would be google search - pagination has max 10 pages, and you can go one by one, or jump few pages ahead/backward.

Does anybody know such component?

Upvotes: 2

Views: 428

Answers (3)

Maciej Miklas
Maciej Miklas

Reputation: 3330

I was unable to find lib with such data provider, so I've implemented one - its called IterableGridView

Here is the code: https://github.com/maciejmiklas/cyclop/tree/master/cyclop-wicket-components

Iterable Grid View is based on Wicket's GridView, however it does not work with IDataProvider but with IterableDataProvider. This new data provider relies only on plain java iterator - size information is not needed, and there is also no need to create range iterators for each page.

final List<String> myGridData = new ArrayList<>();
myGridData.add("value 1");
myGridData.add("value 2");

IterableDataProvider<String> iterableDataProvider = new IterableDataProvider<String>(10) {
    @Override
    protected Iterator<String> iterator() {
        return myGridData.iterator();
    }

    @Override
    public IModel<String> model(String s) {
        return Model.of(s);
    }

    @Override
    public void detach() {
    }
};

IterableGridView<String> myGrid = new IterableGridView<String>("myGrid", iterableDataProvider) {
    @Override
    protected void populateEmptyItem(Item<String> item) {
        item.add(new Label("myValue"));
    }

    @Override
    protected void populateItem(Item<String> item) {
        item.add(new Label("myValue", item.getModelObject()));
    }
};

add(myGrid);

myGrid.setItemsPerPage(10);

// you have to use custom pager and not AjaxPagingNavigator
IterablePagingNavigator pager = new IterablePagingNavigator("rowNamesListPager", rowNamesList);
resultTable.add(pager);

Upvotes: 1

Domas Poliakas
Domas Poliakas

Reputation: 876

My approach to something like that would be the following (that is using the regular DataProvider):

  1. Determine the max displayed pages number (so in the google example, that would be 10 pages)
  2. Whenever size() is called I estimate if there will be more results than [results per page]*[current page] + [max pages]*[results per page];
    • if yes, then return [results per page] * ([current page] + [max pages]) - 1
    • else return the exact amount

That would make wicket think that there are [current page] + [max pages] pages worth of results at any given time. So at any given point you would only have to know if there are [max pages] worth of results more, rather than the exact amount of results.

The size() is used to determine the first and count parameter values on the iterator() function, as well as pagination sizes, so it doesn't have to actually be the size of the result set, it can be a value that would indicate how many results you want displayed, and worry about how many more you want displayed when you get closer to that.

However, the intended behaviour of size() is to display the actual size of the results, so any other components or behaviours you use on the GridView should be checked for side-effects, as they could potentially suffer from unexpected results.

Upvotes: 1

Martin
Martin

Reputation: 1273

I had a very similar problem here. Boris Pavlović pointed out i could use an infinite scrolling solution like this.

But i still ended up using a regular DataView with an IDataProvider with a default wicket ajax page navigator. I limited query results to ~100 (10 per page) and cached the results in the IDataProvider and used the size() on the list. When size() returned same as Maxresults (100) then I give a warning, the user usually doesn't go beyond page 2 (also like google).

Upvotes: 1

Related Questions