How to add custom/override pagination for datacontainers

Hi

Having group table to display customer record by applying filter.I have used service delegate to get customer list instead of jpql. However I have a problem that the to set paging for datacontainers.So say the sql (without the limits set) returns 500 records we only want to display 100 lines in the table in one go and then we can page through the data. The paging is where we would then change the firstresult in the datacontainerservice to get the correct 100 subset of data depending on the page selected in the table on the gui.So can you help how can I acheive this in cuba.

Any help or advice would be greatly appreciated.

Thanks

Hi,

I assume you have generated a loadDelegate for the collection container.
This delegate method receives a LoadContext parameter which contains firstResult and maxResults options. Use these values in your SQL query.

    @Install(to = "cardsDl", target = Target.DATA_LOADER)
    private List<Card> cardsDlLoadDelegate(LoadContext<Card> loadContext) {
        loadContext.getQuery().getFirstResult();
        loadContext.getQuery().getMaxResults();
        // ...
    }

Hi @albudarov

Thanks for the response. I can see how the getFirstResult and getMaxResults would work and that is similar to how we have used it in the legacy datasource implementation where we have created a custom datasource class that extends CustomCollectionDatasource .

The bit we are struggling with is how to link and display the pagination for the datacontainer/table using the loadDelegate. We have created a service that has our custom native SQL and we can set the first and max results of this but this will only return the number of records requested (say firstResult=0, maxResults =100 will only return 100 records) but the complete dataset might be 1000. Without setting the datacontainer count how does the datacontainer know how many records there are in total, how many pages to display etc. As it currently stands as we are only returning a small subset of actual records we want to display in one go (ie 100) and in this case the table never has pagination as it only has 100 records and a dataset count of 100.

In the legacy datasource that extends CustomCollectionDatasource we had overridden the getCount() method where we had some custom native sql to get the total count of records and this then fed into the pagination. We canā€™t see how to do the same?

Thanks
David

Ah, I get it. Yes, you also need to supply getCount().
Its delegate method is in the other component - in the table or dataGrid.
image

    @Install(to = "cardsTable", subject = "rowsCountTotalCountDelegate")
    private Long cardsTableRowsCountTotalCountDelegate(DataLoadContext dataLoadContext) {
        return 0L;
    }

Itā€™s the tableā€™s rowCount who actually is responsible for controlling the paging process.

Hi @albudarov

What you have said make complete sense. However I canā€™t define a component ā€˜simplePaginationā€™. Iā€™ve tried defining in various places within the XML (including under the table component) but it complains that no component of simplePagination exists.

Iā€™ve also followed Count [?] button does not call DataLoader delegate - #2 Š¾Ń‚ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»Ń albudarov but I canā€™t get the rowountDelegate to fire which I am guessing is because this works when you click on the ā€˜?ā€™ in the pagination/row count component of the table, which I canā€™t currently get to display.

Any thoughts?

Thanks in advance
David

Iā€™ve modified my answer.

Hi @albudarov

Iā€™ve followed your suggestion but I canā€™t get the tableRowsCountTotalCountDelegate to fire so canā€™t set the rows count. Iā€™ve attached a simple project that has the basics of what Iā€™m trying to get working. Any suggestions on what Iā€™m missing?
untitled2.zip (490.9 KB)

Thanks
David

Hi @albudarov

Iā€™ve tried several ways to get the the tableRowsCountTotalCountDelegate to fire but canā€™t figure out how or where this is called from:

    @Install(to = "table", subject = "rowsCountTotalCountDelegate")
private Long tableRowsCountTotalCountDelegate(DataLoadContext dataLoadContext) {
    return Long.valueOf(customerDataContainerService.getCount());
} 

I would have expected this to have fired as part of the table initialization/entity loading. Are you able to advise how to fire this after the custom loadDelegate is completed?

Thanks
David

Hi,
I added this code to the CustomerBrowse controller:

    @Subscribe
    public void onInit(InitEvent event) {
        customersDl.setMaxResults(100);
    }

And the paging component transformed to the expected state and started to call countDelegate when pressing on the question button:

I found the solution by putting breakpoints and tracking the logic in the methods of the com.haulmont.cuba.web.gui.components.WebRowsCount class.

Note that in order for paging to fully work, you need to utilize these parameters passed into the loadDelegate: loadContext.getQuery().getFirstResult() and loadContext.getQuery().getMaxResults().

1 Like

Thanks @albudarov that is exactly what I was after. Thank you :+1: