Enabling pagination to datagrid

HI ,

How to enable pagingation to datagrid with valueCollectionDatasource and pass the pager params to custom service via cuba studio .

Thank you .

Hi,

Suppose you have a service loading the list of user logins and names and you want to show it in DataGrid. Of course you could do it with regular User entity and an appropriate view, but we will use KeyValueEntity and ValueCollectionDatasource for the sake of example.

The service interface:

package com.company.sample.service;

import com.haulmont.cuba.core.entity.KeyValueEntity;

import java.util.List;

public interface UserLoadingService {
    String NAME = "sample_UserLoadingService";

    List<KeyValueEntity> loadUsers(int firstResult, int maxResults);

    long getUsersCount();
}

And implementation:

package com.company.sample.service;

import com.haulmont.cuba.core.Persistence;
import com.haulmont.cuba.core.Transaction;
import com.haulmont.cuba.core.TypedQuery;
import com.haulmont.cuba.core.entity.KeyValueEntity;
import org.springframework.stereotype.Service;

import javax.inject.Inject;
import java.util.List;
import java.util.stream.Collectors;

@Service(UserLoadingService.NAME)
public class UserLoadingServiceBean implements UserLoadingService {

    @Inject
    private Persistence persistence;

    public List<KeyValueEntity> loadUsers(int firstResult, int maxResults) {
        try (Transaction tx = persistence.createTransaction()) {
            TypedQuery<Object[]> query = persistence.getEntityManager().createQuery(
                    "select u.login, u.name from sec$User u order by u.login", Object[].class);
            query.setFirstResult(firstResult);
            query.setMaxResults(maxResults);
            return query.getResultList().stream()
                    .map(fields -> {
                        KeyValueEntity entity = new KeyValueEntity();
                        entity.setValue("login", fields[0]);
                        entity.setValue("name", fields[1]);
                        return entity;
                    })
                    .collect(Collectors.toList());
        }
    }

    @Override
    public long getUsersCount() {
        return persistence.callInTransaction(em ->
                (long) em.createQuery("select count(u) from sec$User u").getSingleResult());
    }

}

In the screen, we define a datasource of a custom class and set maxResults attribute for paging. The dataGrid component has rowsCount element which shows the paging controls:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<window xmlns="http://schemas.haulmont.com/cuba/window.xsd"
        caption="msg://caption"
        class="com.company.sample.web.screens.Screen"
        messagesPack="com.company.sample.web.screens">
    <dsContext>
        <valueCollectionDatasource id="usersDs"
                                   datasourceClass="com.company.sample.web.screens.UserValuesDatasource"
                                   maxResults="50">
            <properties>
                <property datatype="string"
                          name="login"/>
                <property datatype="string"
                          name="name"/>
            </properties>
        </valueCollectionDatasource>
    </dsContext>
    <layout>
        <dataGrid datasource="usersDs"
                  height="100%"
                  width="100%">
            <columns>
                <column property="login"/>
                <column property="name"/>
            </columns>
            <rowsCount/>
        </dataGrid>
    </layout>
</window>

The datasource just delegates to our service. Overriding of the getCount() method is required for correct work of paging controls:

package com.company.sample.web.screens;

import com.company.sample.service.UserLoadingService;
import com.haulmont.cuba.core.entity.KeyValueEntity;
import com.haulmont.cuba.core.global.AppBeans;
import com.haulmont.cuba.gui.data.impl.CustomValueCollectionDatasource;

import java.util.Collection;
import java.util.Map;

public class UserValuesDatasource extends CustomValueCollectionDatasource {

    private final UserLoadingService service = AppBeans.get(UserLoadingService.class);

    @Override
    protected Collection<KeyValueEntity> getEntities(Map<String, Object> params) {
        return service.loadUsers(firstResult, maxResults);
    }

    @Override
    public int getCount() {
        return (int) service.getUsersCount();
    }
}

The whole project is attached:
sample.zip (89.9 KB)

Please note that the custom service is not strictly required here, we could use DataManager’s loadValues() and getCount() methods.

2 Likes