Skip to Content
Frontend Integration

Frontend Integration

On the server side, Picnic receives the grid’s load options, executes the SQL query, and returns a response in the format expected by the frontend library.

On the frontend side, you need to:

  1. Enable server/remote mode on the grid
  2. Send the load options to the server
  3. Pass the response to the grid’s callback

Picnic returns an object that is directly consumable by the grid’s callback — no frontend transformation required.


AG Grid Enterprise (Server-Side Row Model)

jQuery / Vanilla JS

// 1. Enable server mode var gridOptions = { rowModelType: 'serverSide', pagination: true, paginationPageSize: 20, cacheBlockSize: 20, columnDefs: [...] }; // 2. Datasource var datasource = { getRows: function(params) { jQuery.ajax({ url: '/app/controller?action=loadData', method: 'POST', contentType: 'application/json', data: JSON.stringify(params.request), success: function(response) { params.success(response); }, error: function() { params.fail(); } }); } }; gridApi.setGridOption('serverSideDatasource', datasource);

React

import { AgGridReact } from 'ag-grid-react'; function MyGrid() { const datasource = { getRows: (params) => { fetch('/app/controller?action=loadData', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(params.request) }) .then(res => res.json()) .then(response => params.success(response)) .catch(() => params.fail()); } }; const onGridReady = (params) => { params.api.setGridOption('serverSideDatasource', datasource); }; return ( <AgGridReact rowModelType="serverSide" pagination={true} paginationPageSize={20} cacheBlockSize={20} columnDefs={columnDefs} onGridReady={onGridReady} /> ); }

Vue 3

<template> <ag-grid-vue :rowModelType="'serverSide'" :pagination="true" :paginationPageSize="20" :cacheBlockSize="20" :columnDefs="columnDefs" @grid-ready="onGridReady" /> </template> <script setup> import { AgGridVue } from 'ag-grid-vue3'; const datasource = { getRows: (params) => { fetch('/app/controller?action=loadData', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(params.request) }) .then(res => res.json()) .then(response => params.success(response)) .catch(() => params.fail()); } }; const onGridReady = (params) => { params.api.setGridOption('serverSideDatasource', datasource); }; </script>

Angular

import { Component } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { IServerSideDatasource } from 'ag-grid-community'; @Component({ template: ` <ag-grid-angular [rowModelType]="'serverSide'" [pagination]="true" [paginationPageSize]="20" [cacheBlockSize]="20" [columnDefs]="columnDefs" (gridReady)="onGridReady($event)"> </ag-grid-angular> ` }) export class MyGridComponent { constructor(private http: HttpClient) {} onGridReady(params: any) { const datasource: IServerSideDatasource = { getRows: (p) => { this.http.post('/app/controller?action=loadData', p.request).subscribe({ next: (response) => p.success(response), error: () => p.fail() }); } }; params.api.setGridOption('serverSideDatasource', datasource); } }

DevExtreme DataGrid / PivotGrid

jQuery / Vanilla JS

// 1. CustomStore with remoteOperations var customStore = new DevExpress.data.CustomStore({ key: 'id', load: function(loadOptions) { var deferred = $.Deferred(); jQuery.ajax({ url: '/app/controller?action=loadData', method: 'POST', contentType: 'application/json', data: JSON.stringify(loadOptions), success: function(response) { deferred.resolve(response); }, error: function(xhr, status, error) { deferred.reject(error); } }); return deferred.promise(); } }); // 2. Grid with remoteOperations $('#gridContainer').dxDataGrid({ dataSource: { store: customStore }, remoteOperations: { paging: true, sorting: true, filtering: true, grouping: true, summary: true } });

React

import DataGrid from 'devextreme-react/data-grid'; import CustomStore from 'devextreme/data/custom_store'; function MyGrid() { const store = new CustomStore({ key: 'id', load: (loadOptions) => { return fetch('/app/controller?action=loadData', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(loadOptions) }).then(res => res.json()); } }); return ( <DataGrid dataSource={store} remoteOperations={{ paging: true, sorting: true, filtering: true, grouping: true, summary: true }} /> ); }

Vue 3

<template> <DxDataGrid :data-source="store" :remote-operations="remoteOps" /> </template> <script setup> import { DxDataGrid } from 'devextreme-vue/data-grid'; import CustomStore from 'devextreme/data/custom_store'; const store = new CustomStore({ key: 'id', load: (loadOptions) => fetch('/app/controller?action=loadData', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(loadOptions) }).then(res => res.json()) }); const remoteOps = { paging: true, sorting: true, filtering: true, grouping: true, summary: true }; </script>

Angular

import { Component } from '@angular/core'; import CustomStore from 'devextreme/data/custom_store'; @Component({ template: ` <dx-data-grid [dataSource]="store" [remoteOperations]="remoteOps"> </dx-data-grid> ` }) export class MyGridComponent { store = new CustomStore({ key: 'id', load: (loadOptions) => fetch('/app/controller?action=loadData', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(loadOptions) }).then(res => res.json()) }); remoteOps = { paging: true, sorting: true, filtering: true, grouping: true, summary: true }; }

Summary

LibraryServer modeOptions payloadResponse
AG GridrowModelType: 'serverSide'params.request (JSON body)params.success(response)
DevExtremeremoteOperations: { ... }loadOptions (JSON body)deferred.resolve(response)

Supported frameworks: jQuery, React, Vue, Angular (pour AG Grid et DevExtreme).

Last updated on

Frontend Integration