dataProvider for Grid with sort and filter

Hi, friend!
Need help for initialisation dataProvider for Grid with sorting and filtering.
So, sorting i’v won - code below is works.
I think frontend will contains useDataProvider instead of useGridDataProvider,
but how change const dataProvider and what parameters will recieve to Endpoint.getSomething - dont know.
i use React.

Frontend

import { useGridDataProvider } from '@vaadin/hilla-react-crud';

const dataProvider = useGridDataProvider(
	async (pageable) => Endpoint.getSomething(pageable), []
);

<Grid 
dataProvider={dataProvider}
multiSortPriority="append"
multiSort>
	<GridColumnGroup header={<GroupIdHeader/>}>
        <GridColumn
        	header={<GridIdHeader/>}
                path="id"/></GridColumnGroup>
</Grid>


function GroupIdHeader() {
    return (
        <GridSorter path="id">ID</GridSorter>
    );
}
function GridIdHeader() {
    return (
        <GridFilter path="id">
            <TextField clearButtonVisible></TextField>
        </GridFilter>
    );
}

Backend

public @NonNull List<@NonNull Dto> getSomething(Pageable pageable) throws EAppException {
    return service.getDto(pageable);
}


public List<Dto> getDto(Pageable pageable) throws EAppException {
	CriteriaBuilder cb = em.getCriteriaBuilder();
	CriteriaQuery<Dto> cq = cb.createQuery(Dto.class);
	Root<Entity> root = cq.from(Entity.class);
	cq.multiselect(root.get(Entity_.id).alias(Entity_.ID));
	Map<String, Path<?>> fields = new HashMap<>();
	fields.put("id", root.get(Entity_.id));
	cq.orderBy(buildOrder(cb, fields, pageable));
	return em.createQuery(cq).setFirstResult(pageable.getPageNumber() * pageable.getPageSize()).setMaxResults(pageable.getPageSize()).getResultList();
}



private List<Order> buildOrder(CriteriaBuilder cb, Map<String, Path<?>> fields, Pageable order) {
        List<Order> result = new ArrayList<>();
        order.getSort().stream().filter(item -> item.getDirection() != null && item.getProperty() != null)
                .forEach(data -> {
                    if (Sort.Direction.ASC.equals(data.getDirection()))
                        result.add(cb.asc(fields.get(data.getProperty())));
                    else
                        result.add(cb.desc(fields.get(data.getProperty())));
                });
        return result;
}

Hi, for least changes to your existing code, you could try the following:

  • Create a separate ref for the grid filters, use it in useDataProvider
import { useDataProvider } from "@vaadin/hilla-react-crud";

const filtersRef = useRef<GridFilterDefinition[]>([]);

const { dataProvider: hillaDataProvider, refresh } = useDataProvider<Dto>({
  list: (pageable) => Endpoint.getSomething(pageable, filtersRef.current),
});

const dataProvider: GridDataProvider<Dto> = useCallback(
  async (params, callback) => {
    filtersRef.current = params.filters;
    await hillaDataProvider(params, callback);
  },
  []
);
  • Create Java version of GridFilterDefinition and update the endpoint method to use it:
public @NonNull List<@NonNull Dto> getSomething(Pageable pageable, List<GridFilterDefinition> filters) throws EAppException {
    return service.getDto(pageable, filters);
}

public record GridFilterDefinition(String path, String value) {
}

Tomi, u are my hero of the day - it works. Thank u very much!

1 Like