Local data in React Grid component

3 Sep 202424 minutes to read

The Syncfusion Grid offers a straightforward way to bind local data, such as arrays or JSON objects, to the grid component. This feature allows you to display and manipulate data within the grid without the need for external server calls, making it particularly useful for scenarios where you’re working with static or locally stored data.

To achieve this, you can assign a JavaScript object array to the dataSource property. Additionally, you have an option to provide the local data source using an instance of the DataManager.

The following example demonstrates how to utilize the local data binding feature in the React Grid component:

import { ColumnDirective, ColumnsDirective, GridComponent } from '@syncfusion/ej2-react-grids';
import * as React from 'react';
import { data } from './datasource';
function App() {
    return <GridComponent dataSource={data.slice(0, 7)}>
        <ColumnsDirective>
            <ColumnDirective field='OrderID' headerText='Order ID' width='120' textAlign="Right"/>
            <ColumnDirective field='CustomerID' headerText='Customer ID' width='150'/>
            <ColumnDirective field='ShipCity' headerText='Ship City' width='150'/>
            <ColumnDirective field='ShipName' headerText='Ship Name' width='150'/>
        </ColumnsDirective>
    </GridComponent>;
}
;
export default App;
import { ColumnDirective, ColumnsDirective, GridComponent } from '@syncfusion/ej2-react-grids';
import * as React from 'react';
import { data } from './datasource';

function App() {
    return <GridComponent dataSource={data.slice(0, 7)}>
        <ColumnsDirective>
            <ColumnDirective field='OrderID' headerText='Order ID' width='120' textAlign="Right" />
            <ColumnDirective field='CustomerID' headerText='Customer ID' width='150' />
            <ColumnDirective field='ShipCity' headerText='Ship City' width='150' />
            <ColumnDirective field='ShipName' headerText='Ship Name' width='150' />
        </ColumnsDirective>
    </GridComponent>
};
export default App;
export let data = [
    {
        OrderID: 10248, CustomerID: 'VINET', EmployeeID: 5, OrderDate: new Date(8364186e5),
        ShipName: 'Vins et alcools Chevalier', ShipCity: 'Reims', ShipAddress: '59 rue de l Abbaye',
        ShipRegion: 'CJ', ShipPostalCode: '51100', ShipCountry: 'France', Freight: 32.38, Verified: !0
    },
    {
        OrderID: 10249, CustomerID: 'TOMSP', EmployeeID: 6, OrderDate: new Date(836505e6),
        ShipName: 'Toms Spezialitäten', ShipCity: 'Münster', ShipAddress: 'Luisenstr. 48',
        ShipRegion: 'CJ', ShipPostalCode: '44087', ShipCountry: 'Germany', Freight: 11.61, Verified: !1
    },
    {
        OrderID: 10250, CustomerID: 'HANAR', EmployeeID: 4, OrderDate: new Date(8367642e5),
        ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67',
        ShipRegion: 'RJ', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 65.83, Verified: !0
    },
    {
        OrderID: 10251, CustomerID: 'VICTE', EmployeeID: 3, OrderDate: new Date(8367642e5),
        ShipName: 'Victuailles en stock', ShipCity: 'Lyon', ShipAddress: '2, rue du Commerce',
        ShipRegion: 'CJ', ShipPostalCode: '69004', ShipCountry: 'France', Freight: 41.34, Verified: !0
    },
    {
        OrderID: 10252, CustomerID: 'SUPRD', EmployeeID: 4, OrderDate: new Date(8368506e5),
        ShipName: 'Suprêmes délices', ShipCity: 'Charleroi', ShipAddress: 'Boulevard Tirou, 255',
        ShipRegion: 'CJ', ShipPostalCode: 'B-6000', ShipCountry: 'Belgium', Freight: 51.3, Verified: !0
    },
    {
        OrderID: 10253, CustomerID: 'HANAR', EmployeeID: 3, OrderDate: new Date(836937e6),
        ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67',
        ShipRegion: 'RJ', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 58.17, Verified: !0
    },
    {
        OrderID: 10254, CustomerID: 'CHOPS', EmployeeID: 5, OrderDate: new Date(8370234e5),
        ShipName: 'Chop-suey Chinese', ShipCity: 'Bern', ShipAddress: 'Hauptstr. 31',
        ShipRegion: 'CJ', ShipPostalCode: '3012', ShipCountry: 'Switzerland', Freight: 22.98, Verified: !1
    },
    {
        OrderID: 10255, CustomerID: 'RICSU', EmployeeID: 9, OrderDate: new Date(8371098e5),
        ShipName: 'Richter Supermarkt', ShipCity: 'Genève', ShipAddress: 'Starenweg 5',
        ShipRegion: 'CJ', ShipPostalCode: '1204', ShipCountry: 'Switzerland', Freight: 148.33, Verified: !0
    },
    {
        OrderID: 10256, CustomerID: 'WELLI', EmployeeID: 3, OrderDate: new Date(837369e6),
        ShipName: 'Wellington Importadora', ShipCity: 'Resende', ShipAddress: 'Rua do Mercado, 12',
        ShipRegion: 'SP', ShipPostalCode: '08737-363', ShipCountry: 'Brazil', Freight: 13.97, Verified: !1
    },
    {
        OrderID: 10257, CustomerID: 'HILAA', EmployeeID: 4, OrderDate: new Date(8374554e5),
        ShipName: 'HILARION-Abastos', ShipCity: 'San Cristóbal', ShipAddress: 'Carrera 22 con Ave. Carlos Soublette #8-35',
        ShipRegion: 'Táchira', ShipPostalCode: '5022', ShipCountry: 'Venezuela', Freight: 81.91, Verified: !0
    },
    {
        OrderID: 10258, CustomerID: 'ERNSH', EmployeeID: 1, OrderDate: new Date(8375418e5),
        ShipName: 'Ernst Handel', ShipCity: 'Graz', ShipAddress: 'Kirchgasse 6',
        ShipRegion: 'CJ', ShipPostalCode: '8010', ShipCountry: 'Austria', Freight: 140.51, Verified: !0
    },
    {
        OrderID: 10259, CustomerID: 'CENTC', EmployeeID: 4, OrderDate: new Date(8376282e5),
        ShipName: 'Centro comercial Moctezuma', ShipCity: 'México D.F.', ShipAddress: 'Sierras de Granada 9993',
        ShipRegion: 'CJ', ShipPostalCode: '05022', ShipCountry: 'Mexico', Freight: 3.25, Verified: !1
    },
    {
        OrderID: 10260, CustomerID: 'OTTIK', EmployeeID: 4, OrderDate: new Date(8377146e5),
        ShipName: 'Ottilies Käseladen', ShipCity: 'Köln', ShipAddress: 'Mehrheimerstr. 369',
        ShipRegion: 'CJ', ShipPostalCode: '50739', ShipCountry: 'Germany', Freight: 55.09, Verified: !0
    },
    {
        OrderID: 10261, CustomerID: 'QUEDE', EmployeeID: 4, OrderDate: new Date(8377146e5),
        ShipName: 'Que Delícia', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua da Panificadora, 12',
        ShipRegion: 'RJ', ShipPostalCode: '02389-673', ShipCountry: 'Brazil', Freight: 3.05, Verified: !1
    },
    {
        OrderID: 10262, CustomerID: 'RATTC', EmployeeID: 8, OrderDate: new Date(8379738e5),
        ShipName: 'Rattlesnake Canyon Grocery', ShipCity: 'Albuquerque', ShipAddress: '2817 Milton Dr.',
        ShipRegion: 'NM', ShipPostalCode: '87110', ShipCountry: 'USA', Freight: 48.29, Verified: !0
    }
];
export let data: Object[] = [
    {
        OrderID: 10248, CustomerID: 'VINET', EmployeeID: 5, OrderDate: new Date(8364186e5),
        ShipName: 'Vins et alcools Chevalier', ShipCity: 'Reims', ShipAddress: '59 rue de l Abbaye',
        ShipRegion: 'CJ', ShipPostalCode: '51100', ShipCountry: 'France', Freight: 32.38, Verified: !0
    },
    {
        OrderID: 10249, CustomerID: 'TOMSP', EmployeeID: 6, OrderDate: new Date(836505e6),
        ShipName: 'Toms Spezialitäten', ShipCity: 'Münster', ShipAddress: 'Luisenstr. 48',
        ShipRegion: 'CJ', ShipPostalCode: '44087', ShipCountry: 'Germany', Freight: 11.61, Verified: !1
    },
    {
        OrderID: 10250, CustomerID: 'HANAR', EmployeeID: 4, OrderDate: new Date(8367642e5),
        ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67',
        ShipRegion: 'RJ', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 65.83, Verified: !0
    },
    {
        OrderID: 10251, CustomerID: 'VICTE', EmployeeID: 3, OrderDate: new Date(8367642e5),
        ShipName: 'Victuailles en stock', ShipCity: 'Lyon', ShipAddress: '2, rue du Commerce',
        ShipRegion: 'CJ', ShipPostalCode: '69004', ShipCountry: 'France', Freight: 41.34, Verified: !0
    },
    {
        OrderID: 10252, CustomerID: 'SUPRD', EmployeeID: 4, OrderDate: new Date(8368506e5),
        ShipName: 'Suprêmes délices', ShipCity: 'Charleroi', ShipAddress: 'Boulevard Tirou, 255',
        ShipRegion: 'CJ', ShipPostalCode: 'B-6000', ShipCountry: 'Belgium', Freight: 51.3, Verified: !0
    },
    {
        OrderID: 10253, CustomerID: 'HANAR', EmployeeID: 3, OrderDate: new Date(836937e6),
        ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67',
        ShipRegion: 'RJ', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 58.17, Verified: !0
    },
    {
        OrderID: 10254, CustomerID: 'CHOPS', EmployeeID: 5, OrderDate: new Date(8370234e5),
        ShipName: 'Chop-suey Chinese', ShipCity: 'Bern', ShipAddress: 'Hauptstr. 31',
        ShipRegion: 'CJ', ShipPostalCode: '3012', ShipCountry: 'Switzerland', Freight: 22.98, Verified: !1
    },
    {
        OrderID: 10255, CustomerID: 'RICSU', EmployeeID: 9, OrderDate: new Date(8371098e5),
        ShipName: 'Richter Supermarkt', ShipCity: 'Genève', ShipAddress: 'Starenweg 5',
        ShipRegion: 'CJ', ShipPostalCode: '1204', ShipCountry: 'Switzerland', Freight: 148.33, Verified: !0
    },
    {
        OrderID: 10256, CustomerID: 'WELLI', EmployeeID: 3, OrderDate: new Date(837369e6),
        ShipName: 'Wellington Importadora', ShipCity: 'Resende', ShipAddress: 'Rua do Mercado, 12',
        ShipRegion: 'SP', ShipPostalCode: '08737-363', ShipCountry: 'Brazil', Freight: 13.97, Verified: !1
    },
    {
        OrderID: 10257, CustomerID: 'HILAA', EmployeeID: 4, OrderDate: new Date(8374554e5),
        ShipName: 'HILARION-Abastos', ShipCity: 'San Cristóbal', ShipAddress: 'Carrera 22 con Ave. Carlos Soublette #8-35',
        ShipRegion: 'Táchira', ShipPostalCode: '5022', ShipCountry: 'Venezuela', Freight: 81.91, Verified: !0
    },
    {
        OrderID: 10258, CustomerID: 'ERNSH', EmployeeID: 1, OrderDate: new Date(8375418e5),
        ShipName: 'Ernst Handel', ShipCity: 'Graz', ShipAddress: 'Kirchgasse 6',
        ShipRegion: 'CJ', ShipPostalCode: '8010', ShipCountry: 'Austria', Freight: 140.51, Verified: !0
    },
    {
        OrderID: 10259, CustomerID: 'CENTC', EmployeeID: 4, OrderDate: new Date(8376282e5),
        ShipName: 'Centro comercial Moctezuma', ShipCity: 'México D.F.', ShipAddress: 'Sierras de Granada 9993',
        ShipRegion: 'CJ', ShipPostalCode: '05022', ShipCountry: 'Mexico', Freight: 3.25, Verified: !1
    },
    {
        OrderID: 10260, CustomerID: 'OTTIK', EmployeeID: 4, OrderDate: new Date(8377146e5),
        ShipName: 'Ottilies Käseladen', ShipCity: 'Köln', ShipAddress: 'Mehrheimerstr. 369',
        ShipRegion: 'CJ', ShipPostalCode: '50739', ShipCountry: 'Germany', Freight: 55.09, Verified: !0
    },
    {
        OrderID: 10261, CustomerID: 'QUEDE', EmployeeID: 4, OrderDate: new Date(8377146e5),
        ShipName: 'Que Delícia', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua da Panificadora, 12',
        ShipRegion: 'RJ', ShipPostalCode: '02389-673', ShipCountry: 'Brazil', Freight: 3.05, Verified: !1
    },
    {
        OrderID: 10262, CustomerID: 'RATTC', EmployeeID: 8, OrderDate: new Date(8379738e5),
        ShipName: 'Rattlesnake Canyon Grocery', ShipCity: 'Albuquerque', ShipAddress: '2817 Milton Dr.',
        ShipRegion: 'NM', ShipPostalCode: '87110', ShipCountry: 'USA', Freight: 48.29, Verified: !0
    }];

Binding data from excel file

The Syncfusion Grid component allows you to import data from Excel files into your web application for display and manipulation within the grid. This feature streamlines the process of transferring Excel data to a web-based environment. This can be achieved by using Uploader component change event.

To import excel data in to grid, you can follow these steps:

  1. Import excel file using Uploader component.
  2. Parse the excel file data using XLSX library.
  3. Bind the JSON to the grid component.

The following example demonstrates how to import Excel data into the grid by utilizing the Uploader component’s change event along with the XLSX library:

import { L10n } from '@syncfusion/ej2-base';
import { GridComponent } from '@syncfusion/ej2-react-grids';
import { UploaderComponent } from '@syncfusion/ej2-react-inputs';
import * as React from 'react';
import { data } from './datasource';

function App() {
  let grid;
  const path = {
    saveUrl: 'https://services.syncfusion.com/react/production/api/FileUploader/Save',
    removeUrl: 'https://services.syncfusion.com/react/production/api/FileUploader/Remove'
  };
  const dropElement = document.getElementsByClassName('control-fluid')[0];
  const parseExcel = (file) => {
    var reader = new FileReader();
    reader.onload = (e) => {
      var data = (e.target).result;
      var workbook = XLSX.read(data, { type: 'array' });
      workbook.SheetNames.forEach((sheetName) => {
        var XL_row_object = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName]);
        grid.dataSource = XL_row_object;
      });
    };
    reader.readAsArrayBuffer(file.rawFile);
  };
  const onSuccess = (args) => {
    var files = args.file;
    if (files)
      parseExcel(files[0]);
  }
  const onRemove = () => {
    grid.dataSource = [];
  }
  return (<div>
    <UploaderComponent asyncSettings={path} removing={onRemove} dropArea={dropElement} change={onSuccess}></UploaderComponent>
    <GridComponent ref={g => grid = g}></GridComponent>
  </div>
  );
};
export default App;
import { L10n } from '@syncfusion/ej2-base';
import { GridComponent } from '@syncfusion/ej2-react-grids';
import { UploaderComponent } from '@syncfusion/ej2-react-inputs';
import * as React from 'react';
import { data } from './datasource';
// import * as XLSX from 'xlsx';


function App() {
  let grid: GridComponent | null;
  const path: Object = {
    saveUrl: 'https://services.syncfusion.com/react/production/api/FileUploader/Save',
    removeUrl: 'https://services.syncfusion.com/react/production/api/FileUploader/Remove'
  };
  const dropElement: HTMLElement = document.getElementsByClassName('control-fluid')[0] as HTMLElement;
  const parseExcel = (file: any) => {
    var reader = new FileReader();
    reader.onload = (e) => {
      var data = ((e as any).target).result;
      var workbook = XLSX.read(data, { type: 'array' });
      workbook.SheetNames.forEach((sheetName: any) => {
        var XL_row_object = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName]);
        (grid as GridComponent).dataSource = XL_row_object;
      });
    };
    reader.readAsArrayBuffer(file.rawFile);
  };
  const onSuccess = (args: any) => {
    var files = args.file;
    if (files)
      parseExcel(files[0]);
  }
  const onRemove = (args: any) => {
    (grid as GridComponent).dataSource = [];
  }
  return (<div>
    <UploaderComponent asyncSettings={path} removing={onRemove} dropArea={dropElement} change={onSuccess}></UploaderComponent>
    <GridComponent ref={g => grid = g}></GridComponent>
  </div>
  );
};
export default App;
export let data = [
    {
        OrderID: 10248, CustomerID: 'VINET', EmployeeID: 5, OrderDate: new Date(8364186e5),
        ShipName: 'Vins et alcools Chevalier', ShipCity: 'Reims', ShipAddress: '59 rue de l Abbaye',
        ShipRegion: 'CJ', ShipPostalCode: '51100', ShipCountry: 'France', Freight: 32.38, Verified: !0
    },
    {
        OrderID: 10249, CustomerID: 'TOMSP', EmployeeID: 6, OrderDate: new Date(836505e6),
        ShipName: 'Toms Spezialitäten', ShipCity: 'Münster', ShipAddress: 'Luisenstr. 48',
        ShipRegion: 'CJ', ShipPostalCode: '44087', ShipCountry: 'Germany', Freight: 11.61, Verified: !1
    },
    {
        OrderID: 10250, CustomerID: 'HANAR', EmployeeID: 4, OrderDate: new Date(8367642e5),
        ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67',
        ShipRegion: 'RJ', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 65.83, Verified: !0
    },
    {
        OrderID: 10251, CustomerID: 'VICTE', EmployeeID: 3, OrderDate: new Date(8367642e5),
        ShipName: 'Victuailles en stock', ShipCity: 'Lyon', ShipAddress: '2, rue du Commerce',
        ShipRegion: 'CJ', ShipPostalCode: '69004', ShipCountry: 'France', Freight: 41.34, Verified: !0
    },
    {
        OrderID: 10252, CustomerID: 'SUPRD', EmployeeID: 4, OrderDate: new Date(8368506e5),
        ShipName: 'Suprêmes délices', ShipCity: 'Charleroi', ShipAddress: 'Boulevard Tirou, 255',
        ShipRegion: 'CJ', ShipPostalCode: 'B-6000', ShipCountry: 'Belgium', Freight: 51.3, Verified: !0
    },
    {
        OrderID: 10253, CustomerID: 'HANAR', EmployeeID: 3, OrderDate: new Date(836937e6),
        ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67',
        ShipRegion: 'RJ', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 58.17, Verified: !0
    },
    {
        OrderID: 10254, CustomerID: 'CHOPS', EmployeeID: 5, OrderDate: new Date(8370234e5),
        ShipName: 'Chop-suey Chinese', ShipCity: 'Bern', ShipAddress: 'Hauptstr. 31',
        ShipRegion: 'CJ', ShipPostalCode: '3012', ShipCountry: 'Switzerland', Freight: 22.98, Verified: !1
    },
    {
        OrderID: 10255, CustomerID: 'RICSU', EmployeeID: 9, OrderDate: new Date(8371098e5),
        ShipName: 'Richter Supermarkt', ShipCity: 'Genève', ShipAddress: 'Starenweg 5',
        ShipRegion: 'CJ', ShipPostalCode: '1204', ShipCountry: 'Switzerland', Freight: 148.33, Verified: !0
    },
    {
        OrderID: 10256, CustomerID: 'WELLI', EmployeeID: 3, OrderDate: new Date(837369e6),
        ShipName: 'Wellington Importadora', ShipCity: 'Resende', ShipAddress: 'Rua do Mercado, 12',
        ShipRegion: 'SP', ShipPostalCode: '08737-363', ShipCountry: 'Brazil', Freight: 13.97, Verified: !1
    },
    {
        OrderID: 10257, CustomerID: 'HILAA', EmployeeID: 4, OrderDate: new Date(8374554e5),
        ShipName: 'HILARION-Abastos', ShipCity: 'San Cristóbal', ShipAddress: 'Carrera 22 con Ave. Carlos Soublette #8-35',
        ShipRegion: 'Táchira', ShipPostalCode: '5022', ShipCountry: 'Venezuela', Freight: 81.91, Verified: !0
    },
    {
        OrderID: 10258, CustomerID: 'ERNSH', EmployeeID: 1, OrderDate: new Date(8375418e5),
        ShipName: 'Ernst Handel', ShipCity: 'Graz', ShipAddress: 'Kirchgasse 6',
        ShipRegion: 'CJ', ShipPostalCode: '8010', ShipCountry: 'Austria', Freight: 140.51, Verified: !0
    },
    {
        OrderID: 10259, CustomerID: 'CENTC', EmployeeID: 4, OrderDate: new Date(8376282e5),
        ShipName: 'Centro comercial Moctezuma', ShipCity: 'México D.F.', ShipAddress: 'Sierras de Granada 9993',
        ShipRegion: 'CJ', ShipPostalCode: '05022', ShipCountry: 'Mexico', Freight: 3.25, Verified: !1
    },
    {
        OrderID: 10260, CustomerID: 'OTTIK', EmployeeID: 4, OrderDate: new Date(8377146e5),
        ShipName: 'Ottilies Käseladen', ShipCity: 'Köln', ShipAddress: 'Mehrheimerstr. 369',
        ShipRegion: 'CJ', ShipPostalCode: '50739', ShipCountry: 'Germany', Freight: 55.09, Verified: !0
    },
    {
        OrderID: 10261, CustomerID: 'QUEDE', EmployeeID: 4, OrderDate: new Date(8377146e5),
        ShipName: 'Que Delícia', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua da Panificadora, 12',
        ShipRegion: 'RJ', ShipPostalCode: '02389-673', ShipCountry: 'Brazil', Freight: 3.05, Verified: !1
    },
    {
        OrderID: 10262, CustomerID: 'RATTC', EmployeeID: 8, OrderDate: new Date(8379738e5),
        ShipName: 'Rattlesnake Canyon Grocery', ShipCity: 'Albuquerque', ShipAddress: '2817 Milton Dr.',
        ShipRegion: 'NM', ShipPostalCode: '87110', ShipCountry: 'USA', Freight: 48.29, Verified: !0
    }
];
export let data: Object[] = [
    {
        OrderID: 10248, CustomerID: 'VINET', EmployeeID: 5, OrderDate: new Date(8364186e5),
        ShipName: 'Vins et alcools Chevalier', ShipCity: 'Reims', ShipAddress: '59 rue de l Abbaye',
        ShipRegion: 'CJ', ShipPostalCode: '51100', ShipCountry: 'France', Freight: 32.38, Verified: !0
    },
    {
        OrderID: 10249, CustomerID: 'TOMSP', EmployeeID: 6, OrderDate: new Date(836505e6),
        ShipName: 'Toms Spezialitäten', ShipCity: 'Münster', ShipAddress: 'Luisenstr. 48',
        ShipRegion: 'CJ', ShipPostalCode: '44087', ShipCountry: 'Germany', Freight: 11.61, Verified: !1
    },
    {
        OrderID: 10250, CustomerID: 'HANAR', EmployeeID: 4, OrderDate: new Date(8367642e5),
        ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67',
        ShipRegion: 'RJ', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 65.83, Verified: !0
    },
    {
        OrderID: 10251, CustomerID: 'VICTE', EmployeeID: 3, OrderDate: new Date(8367642e5),
        ShipName: 'Victuailles en stock', ShipCity: 'Lyon', ShipAddress: '2, rue du Commerce',
        ShipRegion: 'CJ', ShipPostalCode: '69004', ShipCountry: 'France', Freight: 41.34, Verified: !0
    },
    {
        OrderID: 10252, CustomerID: 'SUPRD', EmployeeID: 4, OrderDate: new Date(8368506e5),
        ShipName: 'Suprêmes délices', ShipCity: 'Charleroi', ShipAddress: 'Boulevard Tirou, 255',
        ShipRegion: 'CJ', ShipPostalCode: 'B-6000', ShipCountry: 'Belgium', Freight: 51.3, Verified: !0
    },
    {
        OrderID: 10253, CustomerID: 'HANAR', EmployeeID: 3, OrderDate: new Date(836937e6),
        ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67',
        ShipRegion: 'RJ', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 58.17, Verified: !0
    },
    {
        OrderID: 10254, CustomerID: 'CHOPS', EmployeeID: 5, OrderDate: new Date(8370234e5),
        ShipName: 'Chop-suey Chinese', ShipCity: 'Bern', ShipAddress: 'Hauptstr. 31',
        ShipRegion: 'CJ', ShipPostalCode: '3012', ShipCountry: 'Switzerland', Freight: 22.98, Verified: !1
    },
    {
        OrderID: 10255, CustomerID: 'RICSU', EmployeeID: 9, OrderDate: new Date(8371098e5),
        ShipName: 'Richter Supermarkt', ShipCity: 'Genève', ShipAddress: 'Starenweg 5',
        ShipRegion: 'CJ', ShipPostalCode: '1204', ShipCountry: 'Switzerland', Freight: 148.33, Verified: !0
    },
    {
        OrderID: 10256, CustomerID: 'WELLI', EmployeeID: 3, OrderDate: new Date(837369e6),
        ShipName: 'Wellington Importadora', ShipCity: 'Resende', ShipAddress: 'Rua do Mercado, 12',
        ShipRegion: 'SP', ShipPostalCode: '08737-363', ShipCountry: 'Brazil', Freight: 13.97, Verified: !1
    },
    {
        OrderID: 10257, CustomerID: 'HILAA', EmployeeID: 4, OrderDate: new Date(8374554e5),
        ShipName: 'HILARION-Abastos', ShipCity: 'San Cristóbal', ShipAddress: 'Carrera 22 con Ave. Carlos Soublette #8-35',
        ShipRegion: 'Táchira', ShipPostalCode: '5022', ShipCountry: 'Venezuela', Freight: 81.91, Verified: !0
    },
    {
        OrderID: 10258, CustomerID: 'ERNSH', EmployeeID: 1, OrderDate: new Date(8375418e5),
        ShipName: 'Ernst Handel', ShipCity: 'Graz', ShipAddress: 'Kirchgasse 6',
        ShipRegion: 'CJ', ShipPostalCode: '8010', ShipCountry: 'Austria', Freight: 140.51, Verified: !0
    },
    {
        OrderID: 10259, CustomerID: 'CENTC', EmployeeID: 4, OrderDate: new Date(8376282e5),
        ShipName: 'Centro comercial Moctezuma', ShipCity: 'México D.F.', ShipAddress: 'Sierras de Granada 9993',
        ShipRegion: 'CJ', ShipPostalCode: '05022', ShipCountry: 'Mexico', Freight: 3.25, Verified: !1
    },
    {
        OrderID: 10260, CustomerID: 'OTTIK', EmployeeID: 4, OrderDate: new Date(8377146e5),
        ShipName: 'Ottilies Käseladen', ShipCity: 'Köln', ShipAddress: 'Mehrheimerstr. 369',
        ShipRegion: 'CJ', ShipPostalCode: '50739', ShipCountry: 'Germany', Freight: 55.09, Verified: !0
    },
    {
        OrderID: 10261, CustomerID: 'QUEDE', EmployeeID: 4, OrderDate: new Date(8377146e5),
        ShipName: 'Que Delícia', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua da Panificadora, 12',
        ShipRegion: 'RJ', ShipPostalCode: '02389-673', ShipCountry: 'Brazil', Freight: 3.05, Verified: !1
    },
    {
        OrderID: 10262, CustomerID: 'RATTC', EmployeeID: 8, OrderDate: new Date(8379738e5),
        ShipName: 'Rattlesnake Canyon Grocery', ShipCity: 'Albuquerque', ShipAddress: '2817 Milton Dr.',
        ShipRegion: 'NM', ShipPostalCode: '87110', ShipCountry: 'USA', Freight: 48.29, Verified: !0
    }];

Binding data and performing CRUD actions via Fetch request

The Syncfusion Grid provides a seamless way to bind data from external sources using Fetch requests, facilitating CRUD (Create, Read, Update, Delete) operations with data retrieved from a server. This feature is particularly valuable for sending data to a server for database updates and asynchronously retrieving data without refreshing the entire web page.

To achieve data binding and perform CRUD actions using Ajax requests in the Syncfusion Grid, follow these steps:

Step 1: Include the Syncfusion Grid in your HTML with necessary configurations:

    <div>
        <ButtonComponent onClick={onClick}>Bind data via Fetch</ButtonComponent>
        <GridComponent ref={g => grid = g} allowPaging={true} allowFiltering={true} editSettings={editSettings} toolbar={toolbar} actionBegin={actionBegin} actionComplete={actionComplete}>
        <ColumnsDirective>
            <ColumnDirective field='OrderID' headerText='Order ID' textAlign="Right" width='120' isPrimaryKey={true} />
            <ColumnDirective field='CustomerID' headerText='CustomerID' width='160' />
            <ColumnDirective field='ShipCity' headerText='ShipCity' textAlign="Right" width='120' />
        </ColumnsDirective>
        <Inject services={[Page, Filter, Edit, Toolbar]} />
        </GridComponent>
    </div>

Step 2: To bind data from an external Fetch request, utilize the dataSource property of the Grid. Fetch data from the server and provide it to the dataSource property using the onSuccess event of the Fetch request.

   const click = () => {
      const fetch= new Fetch("https://localhost:****/Home/Getdata", 'POST');//Use remote server host number instead ****
      fetch.send();
      fetch.onSuccess = (data: string) => {
        grid.dataSource = JSON.parse(data);
    };
    }

On the server side, there is a method named GetData within the HomeController that contains the grid’s data source. When the button is clicked, an Fetch request is sent to fetch the data from the server and bind it to the Grid component.

public class HomeController : Controller
    {        
    public ActionResult Getdata()
        {
            IEnumerable DataSource = OrdersDetails.GetAllRecords();
            return Json(DataSource);
        } 

    //create model class define the properties
    public class OrdersDetails
       {
        public OrdersDetails()
           {

           }
        public OrdersDetails(int OrderID, string CustomerId, int EmployeeId, double Freight, bool Verified, DateTime OrderDate, string ShipCity, string ShipName, string ShipCountry, DateTime ShippedDate, string ShipAddress)
        {
            this.OrderID = OrderID;
            this.CustomerID = CustomerId;
            this.EmployeeID = EmployeeId;
            this.Freight = Freight;
            this.ShipCity = ShipCity;
            this.Verified = Verified;
            this.OrderDate = OrderDate;
            this.ShipName = ShipName;
            this.ShipCountry = ShipCountry;
            this.ShippedDate = ShippedDate;
            this.ShipAddress = ShipAddress;
        }
        //Render data in this method
        public static List<OrdersDetails> GetAllRecords()
        {
            List<OrdersDetails> order = new List<OrdersDetails>();
            int code = 10000;
            for (int i = 1; i < 10; i++)
            {
                order.Add(new OrdersDetails(code + 1, "ALFKI", i + 0, 2.3 * i, false, new DateTime(1991, 05, 15), "Berlin", "Simons bistro", "Denmark", new DateTime(1996, 7, 16), "Kirchgasse 6"));
                order.Add(new OrdersDetails(code + 2, "ANATR", i + 2, 3.3 * i, true, new DateTime(1990, 04, 04), "Madrid", "Queen Cozinha", "Brazil", new DateTime(1996, 9, 11), "Avda. Azteca 123"));
                order.Add(new OrdersDetails(code + 3, "ANTON", i + 1, 4.3 * i, true, new DateTime(1957, 11, 30), "Cholchester", "Frankenversand", "Germany", new DateTime(1996, 10, 7), "Carrera 52 con Ave. Bolívar #65-98 Llano Largo"));
                order.Add(new OrdersDetails(code + 4, "BLONP", i + 3, 5.3 * i, false, new DateTime(1930, 10, 22), "Marseille", "Ernst Handel", "Austria", new DateTime(1996, 12, 30), "Magazinweg 7"));
                order.Add(new OrdersDetails(code + 5, "BOLID", i + 4, 6.3 * i, true, new DateTime(1953, 02, 18), "Tsawassen", "Hanari Carnes", "Switzerland", new DateTime(1997, 12, 3), "1029 - 12th Ave. S."));
                code += 5;
            }
            return order;
        }

        public int? OrderID { get; set; }
        public string CustomerID { get; set; }
        public int? EmployeeID { get; set; }
        public double? Freight { get; set; }
        public string ShipCity { get; set; }
        public bool Verified { get; set; }
        public DateTime OrderDate { get; set; }
        public string ShipName { get; set; }
        public string ShipCountry { get; set; }
        public DateTime ShippedDate { get; set; }
        public string ShipAddress { get; set; }
    }    
}

Step 3: To perform CRUD actions, leverage the actionBegin event. You can cancel the default CRUD operations by utilizing the cancel argument provided by this event. This allows you to dynamically call your server-side method using Fetch, along with the relevant data received from the actionBegin event, to update your server data accordingly.

A. To add a new record using Fetch requests, follow these steps:

       let flag = false;

        const actionBegin = (e: EditEventArgs) => {
            // Initially flag needs to be false in order to enter this condition
            if (!flag) {
                // Add and edit operations
                if (e.requestType == 'save' && ((e as any).action == 'add')) {
                    var editedData = (e as any).data;
                    // The default edit operation is cancelled
                    e.cancel = true;
                    // Here you can send the updated data to your server using fetch call
                    var fetch = new Fetch({
                        url: 'https://localhost:****/Home/Insert',
                        type: 'POST',
                        contentType: 'application/json; charset=utf-8',
                        data: JSON.stringify({ value: editedData })
                    }); //Use remote server host number instead ****
                    fetch.onSuccess = () => {
                        // flag is enabled to skip this execution when grid ends add/edit
                        flag = true;
                        // The added/edited data will be saved in the Grid
                        grid.endEdit();
                    }
                    fetch.onFailure = () => {
                        // Add/edit failed
                        // The flag is disabled if operation is failed so that it can enter the condition on next execution
                        flag = false;
                    }
                    fetch.send();
                }
        }
//insert the record
    public ActionResult Insert(OrdersDetails value)
        {
            OrdersDetails.GetAllRecords().Insert(0, value);
            return Json(value);
        }

B. To edit and save a record using an Fetch request, follow these steps:

        let flag = false;

        const actionBegin = (e: EditEventArgs) => {
            // Initially flag needs to be false in order to enter this condition
            if (!flag) {
                if (e.requestType == 'save' && ((e as any).action == "edit")) {
                    var editedData = (e as any).data;
                    // The default edit operation is cancelled
                    e.cancel = true;
                    // Here you can send the updated data to your server using fetch call
                    var fetch= new Fetch({
                        url: 'https://localhost:****/Home/Update',
                        type: 'POST',
                        contentType: 'application/json; charset=utf-8',
                        data: JSON.stringify({ value: editedData })
                    });//Use remote server host number instead ****
                    fetch.onSuccess = () => {
                        // flag is enabled to skip this execution when grid ends add/edit
                        flag = true;
                        // The added/edited data will be saved in the Grid
                        grid.endEdit();
                    }
                    fetch.onFailure = () => {
                        // Add/edit failed
                        // The flag is disabled if operation is failed so that it can enter the condition on next execution
                        flag = false;
                    }
                    fetch.send();
                }        
            }
        }
//update the record
public ActionResult Update(OrdersDetails value)
        {
            var ord = value;
            OrdersDetails val = OrdersDetails.GetAllRecords().Where(or => or.OrderID == ord.OrderID).FirstOrDefault();
            val.OrderID = ord.OrderID;
            val.EmployeeID = ord.EmployeeID;
            val.CustomerID = ord.CustomerID;
            return Json(value);
        }

C. To delete a record using an Fetch request, follow these steps:

        let flag = false;

        const actionBegin = (e: EditEventArgs) => {
            // Initially flag needs to be false in order to enter this condition
            if (!flag) {
                if (e.requestType == 'delete') {
                    var editedData = (e as any).data;
                    // The default delete operation is cancelled
                    e.cancel = true;
                    // Here you can send the deleted data to your server using fetch call
                    var fetch = new Fetch({
                        url: 'https://localhost:****/Home/Delete',
                        type: 'POST',
                        contentType: 'application/json; charset=utf-8',
                        data: JSON.stringify({ key: editedData[0][grid.getPrimaryKeyFieldNames()[0]] })
                    }) //Use remote server host number instead ****
                    fetch.onSuccess = () => {
                        // flag is enabled to skip this execution when grid deletes record
                        flag = true;
                        // The deleted data will be removed in the Grid
                        grid.deleteRecord();
                    }
                    fetch.onFailure = () => {
                        // Delete failed
                        // The flag is disabled if operation is failed so that it can enter the condition on next execution
                        flag = false;
                    }
                    fetch.send();
                }
            }
    }
//Delete the record
  public ActionResult Delete(int key)
        {
            OrdersDetails.GetAllRecords().Remove(OrdersDetails.GetAllRecords().Where(or => or.OrderID == key).FirstOrDefault());
            var data = OrdersDetails.GetAllRecords();
            return Json(data);
        }

Step 4: In the Fetch success event, you have the flexibility to utilize the Grid’s endEdit and deleteRecord methods to handle the addition, editing, and deletion of corresponding data in the Grid. However, invoking these methods triggers the actionBegin event once again to save the changes in the Grid. To prevent this behavior and maintain control over the execution flow, you can employ a flag variable and manage it within the actionComplete and Fetch failure events: The following code snippet demonstrates this approach:

        const actionComplete = (e: EditEventArgs) => {
            if (e.requestType === 'save' || e.requestType === 'delete') {
                // The flag is disabled after operation is successfully performed so that it can enter the condition on next execution
                flag = false;
            }
        }

The following screenshot represents loading data when the button is clicked and CRUD operations are performed:

Fetch

Display the loading indicator with local data.

The Syncfusion Grid allows you to display a loading indicator while loading local data. This feature is useful when there is a delay in loading data from a local source, and you want to inform the you that the data is being fetched.

To display the loading indicator with local data, you need to set the showSpinner property to true. This property controls the visibility of the loading indicator.

The following example demonstrates how to display the loading indicator in the Syncfusion Grid using the load and created events:

import { ColumnDirective, ColumnsDirective, GridComponent } from '@syncfusion/ej2-react-grids';
import * as React from 'react';
import { lazyLoadData } from './datasource';

function App() {
  let grid: GridComponent | null;
  const load = () => {
    setTimeout(() => {
      (grid as GridComponent).showSpinner();
    }, 200)
    setTimeout(() => {
      (grid as GridComponent).dataSource = lazyLoadData as Object[];
    }, 5000)
  }
  return (<div>
    <GridComponent ref={g => grid = g} height={315} load={load}>
      <ColumnsDirective>
        <ColumnDirective field='OrderID' headerText='OrderID' width='120' textAlign="Right" />
        <ColumnDirective field='CustomerID' headerText='CustomerID' width='150' />
        <ColumnDirective field='Quantity' headerText='Quantity' width='150' />
        <ColumnDirective field='CustomerAddress' headerText='CustomerAddress' width='150' />
      </ColumnsDirective>
    </GridComponent></div>)
};
export default App;

Binding data and performing CRUD actions via AJAX request

The Syncfusion Grid provides a seamless way to bind data from external sources using AJAX requests, facilitating CRUD (Create, Read, Update, Delete) operations with data retrieved from a server. This feature is particularly valuable for sending data to a server for database updates and asynchronously retrieving data without refreshing the entire web page

To achieve data binding and perform CRUD actions using Ajax requests in the Syncfusion Grid, follow these steps:

Step 1: Include the Syncfusion Grid in your HTML with necessary configurations:

    <div>
        <ButtonComponent onClick={onClick}>Bind data via AJAX</ButtonComponent>
        <GridComponent ref={g => grid = g} allowPaging={true} allowFiltering={true} editSettings={editSettings} toolbar={toolbar} actionBegin={actionBegin} actionComplete={actionComplete}>
            <ColumnsDirective>
                <ColumnDirective field='OrderID' headerText='Order ID' textAlign="Right" width='120' isPrimaryKey={true} />
                <ColumnDirective field='CustomerID' headerText='CustomerID' width='160' />
                <ColumnDirective field='ShipCity' headerText='ShipCity' textAlign="Right" width='120' />
            </ColumnsDirective>
            <Inject services={[Page, Filter, Edit, Toolbar]} />
        </GridComponent>
    </div>

Step 2: To bind data from an external AJAX request, utilize the dataSource property of the Grid. Fetch data from the server and provide it to the dataSource property using the onSuccess event of the AJAX request.

   const click = () => {
        const ajax = new Ajax("https://localhost:****/Home/Getdata", 'POST'); //Use remote server host number instead ****
        ajax.send();
        ajax.onSuccess = (data: string) => {
            grid.dataSource = JSON.parse(data);
        };
    }

On the server side, there is a method named GetData within the HomeController that contains the grid’s data source. When the button is clicked, an AJAX request is sent to fetch the data from the server and bind it to the Grid component.

public class HomeController : Controller
    {        
        public ActionResult Getdata()
        {
            var DataSource = OrdersDetails.GetAllRecords();
            return Json(DataSource);
        } 

        //create model class define the properties
        public class OrdersDetails
           {
             public OrdersDetails()
             {

             }
        public OrdersDetails(int OrderID, string CustomerId, int EmployeeId, double Freight, bool Verified, DateTime OrderDate, string ShipCity, string ShipName, string ShipCountry, DateTime ShippedDate, string ShipAddress)
        {
            this.OrderID = OrderID;
            this.CustomerID = CustomerId;
            this.EmployeeID = EmployeeId;
            this.Freight = Freight;
            this.ShipCity = ShipCity;
            this.Verified = Verified;
            this.OrderDate = OrderDate;
            this.ShipName = ShipName;
            this.ShipCountry = ShipCountry;
            this.ShippedDate = ShippedDate;
            this.ShipAddress = ShipAddress;
        }
        //Render data in this method
        public static List<OrdersDetails> GetAllRecords()
        {
            List<OrdersDetails> order = new List<OrdersDetails>();
            int code = 10000;
            for (int i = 1; i < 10; i++)
            {
                order.Add(new OrdersDetails(code + 1, "ALFKI", i + 0, 2.3 * i, false, new DateTime(1991, 05, 15), "Berlin", "Simons bistro", "Denmark", new DateTime(1996, 7, 16), "Kirchgasse 6"));
                order.Add(new OrdersDetails(code + 2, "ANATR", i + 2, 3.3 * i, true, new DateTime(1990, 04, 04), "Madrid", "Queen Cozinha", "Brazil", new DateTime(1996, 9, 11), "Avda. Azteca 123"));
                order.Add(new OrdersDetails(code + 3, "ANTON", i + 1, 4.3 * i, true, new DateTime(1957, 11, 30), "Cholchester", "Frankenversand", "Germany", new DateTime(1996, 10, 7), "Carrera 52 con Ave. Bolívar #65-98 Llano Largo"));
                order.Add(new OrdersDetails(code + 4, "BLONP", i + 3, 5.3 * i, false, new DateTime(1930, 10, 22), "Marseille", "Ernst Handel", "Austria", new DateTime(1996, 12, 30), "Magazinweg 7"));
                order.Add(new OrdersDetails(code + 5, "BOLID", i + 4, 6.3 * i, true, new DateTime(1953, 02, 18), "Tsawassen", "Hanari Carnes", "Switzerland", new DateTime(1997, 12, 3), "1029 - 12th Ave. S."));
                code += 5;
            }
            return order;
        }

        public int? OrderID { get; set; }
        public string CustomerID { get; set; }
        public int? EmployeeID { get; set; }
        public double? Freight { get; set; }
        public string ShipCity { get; set; }
        public bool Verified { get; set; }
        public DateTime OrderDate { get; set; }
        public string ShipName { get; set; }
        public string ShipCountry { get; set; }
        public DateTime ShippedDate { get; set; }
        public string ShipAddress { get; set; }
    }    
}

Step 3: To perform CRUD actions, leverage the actionBegin event. You can cancel the default CRUD operations by utilizing the cancel argument provided by this event. This allows you to dynamically call your server-side method using AJAX, along with the relevant data received from the actionBegin event, to update your server data accordingly.

A. To add a new record using AJAX requests, follow these steps:

       let flag = false;

        const actionBegin = (e: EditEventArgs) => {
            // Initially flag needs to be false in order to enter this condition
            if (!flag) {
                // Add and edit operations
                if (e.requestType == 'save' && ((e as any).action == 'add')) {
                    var editedData = (e as any).data;
                    // The default edit operation is cancelled
                    e.cancel = true;
                    // Here you can send the updated data to your server using AJAX call
                    var ajax = new Ajax({
                        url: 'https://localhost:****/Home/Insert',
                        type: 'POST',
                        contentType: 'application/json; charset=utf-8',
                        data: JSON.stringify({ value: editedData })
                    });  //Use remote server host number instead ****
                    ajax.onSuccess = () => {
                        // flag is enabled to skip this execution when grid ends add/edit
                        flag = true;
                        // The added/edited data will be saved in the Grid
                        grid.endEdit();
                    }
                    ajax.onFailure = () => {
                        // Add/edit failed
                        // The flag is disabled if operation is failed so that it can enter the condition on next execution
                        flag = false;
                    }
                    ajax.send();
                }
        }
//insert the record
       public ActionResult Insert([FromBody] CRUDModel<OrdersDetails> value)
       {

           OrdersDetails.GetAllRecords().Insert(0, value.value);
           return Json(value.value);
       }

B. To edit and save a record using an AJAX request, follow these steps:

        let flag = false;

        const actionBegin = (e: EditEventArgs) => {
            // Initially flag needs to be false in order to enter this condition
            if (!flag) {
                if (e.requestType == 'save' && ((e as any).action == "edit")) {
                    var editedData = (e as any).data;
                    // The default edit operation is cancelled
                    e.cancel = true;
                    // Here you can send the updated data to your server using ajax call
                    var ajax = new Ajax({
                        url: 'https://localhost:****/Home/Update',
                        type: 'POST',
                        contentType: 'application/json; charset=utf-8',
                        data: JSON.stringify({ value: editedData })
                    }); //Use remote server host number instead ****
                    ajax.onSuccess = () => {
                        // flag is enabled to skip this execution when grid ends add/edit
                        flag = true;
                        // The added/edited data will be saved in the Grid
                        grid.endEdit();
                    }
                    ajax.onFailure = () => {
                        // Add/edit failed
                        // The flag is disabled if operation is failed so that it can enter the condition on next execution
                        flag = false;
                    }
                    ajax.send();
                }
        
            }
        }
//update the record
   public ActionResult Update([FromBody] CRUDModel<OrdersDetails> value)
    {
        var ord = value.value;
        OrdersDetails val = OrdersDetails.GetAllRecords().Where(or => or.OrderID == ord.OrderID).FirstOrDefault();
        val.OrderID = ord.OrderID;
        val.EmployeeID = ord.EmployeeID;
        val.CustomerID = ord.CustomerID;
        val.Freight = ord.Freight;
        val.OrderDate = ord.OrderDate;
        val.ShipCity = ord.ShipCity;
        val.ShipCountry = ord.ShipCountry;
        return Json(value.value);
    }

C. To delete a record using an AJAX request, follow these steps:

        let flag = false;

        const actionBegin = (e: EditEventArgs) => {
            // Initially flag needs to be false in order to enter this condition
            if (!flag) {
                if (e.requestType == 'delete') {
                    var editedData = (e as any).data;
                    // The default delete operation is cancelled
                    e.cancel = true;
                    // Here you can send the deleted data to your server using ajax call
                    var ajax = new Ajax({
                        url: 'https://localhost:****/Home/Delete',
                        type: 'POST',
                        contentType: 'application/json; charset=utf-8',
                        data: JSON.stringify({ key: editedData[0][grid.getPrimaryKeyFieldNames()[0]] })
                    }) //Use remote server host number instead ****
                    ajax.onSuccess = () => {
                        // flag is enabled to skip this execution when grid deletes record
                        flag = true;
                        // The deleted data will be removed in the Grid
                        grid.deleteRecord();
                    }
                    ajax.onFailure = () => {
                        // Delete failed
                        // The flag is disabled if operation is failed so that it can enter the condition on next execution
                        flag = false;
                    }
                    ajax.send();
                }
            }
    }
//Delete the record
  public ActionResult Delete(int key)
        {
            OrdersDetails.GetAllRecords().Remove(OrdersDetails.GetAllRecords().Where(or => or.OrderID == key).FirstOrDefault());
            var data = OrdersDetails.GetAllRecords();
            return Json(data);
        }

Step 4: In the AJAX success event, you have the flexibility to utilize the Grid’s endEdit and deleteRecord methods to handle the addition, editing, and deletion of corresponding data in the Grid. However, invoking these methods triggers the actionBegin event once again to save the changes in the Grid. To prevent this behavior and maintain control over the execution flow, you can employ a flag variable and manage it within the actionComplete and AJAX failure events: The following code snippet demonstrates this approach:

        const actionComplete = (e: EditEventArgs) => {
            if (e.requestType === 'save' || e.requestType === 'delete') {
                // The flag is disabled after operation is successfully performed so that it can enter the condition on next execution
                flag = false;
            }
        }

The following screenshot represents loading data when the button is clicked and CRUD operations are performed:

Ajax

Display the loading indicator using AJAX.

The Syncfusion Grid allows you to display a loading indicator while loading data using AJAX. This feature is useful when there is a delay in loading data from data , and you want to inform the you that the data is being fetched. This is particularly beneficial when working with large datasets or under conditions of slower internet connections.

To display the loading indicator with local data, you need to set the showSpinner property to true. This property controls the visibility of the loading indicator.

The following example demonstrates how to display the loading indicator in the Syncfusion Grid using the load and created events:

import { ColumnDirective, ColumnsDirective, GridComponent, Page } from '@syncfusion/ej2-react-grids';
import * as React from 'react';
import { lazyLoadData } from './datasource';

function App() {
  let grid: GridComponent | null;
  let isDataLoading = true;
  const pageSettings: object = { pageSize: 5, pageCount: 3 }
  const load = () => {
    if (isDataLoading) {
        (grid as GridComponent).showSpinner();
        isDataLoading = false;
    }
  }
  const created = () => {
    isDataLoading = true;
    const grid = grid;  // Grid instance
    const ajax = new Ajax('https://services.syncfusion.com/react/production/api/Orders','GET');
    ajax.send();
    ajax.onSuccess = (data: string) => {
        (grid as GridComponent).dataSource = JSON.parse(data);
    };
}
  return (<div>
    <GridComponent ref={g => grid = g} height={315} allowPaging={true} pageSettings={pageSettings} load={load} created={created}>
      <ColumnsDirective>
        <ColumnDirective field='OrderID' headerText='OrderID' width='120' textAlign="Right" />
        <ColumnDirective field='CustomerID' headerText='CustomerID' width='150' />
        <ColumnDirective field='EmployeeID' headerText='EmployeeID' width='150' />
        <ColumnDirective field='ShipCountry' headerText='ShipCountry' width='150' />
      </ColumnsDirective>
      <Inject services={[Page]]} />
    </GridComponent></div>)
};
export default App;

Managing spinner visibility during data loading

Showing a spinner during data loading in the Syncfusion React Grid enhances the experience by providing a visual indication of the loading progress. This feature helps to understand that data is being fetched or processed.

To show or hide a spinner during data loading in the grid, you can utilize the showSpinner and hideSpinner methods provided by the Grid component.

The following example demonstrates how to show and hide the spinner during data loading using external buttons in a grid:

import { ColumnDirective, ColumnsDirective, GridComponent, Inject, Page } from '@syncfusion/ej2-react-grids';
import { ButtonComponent } from '@syncfusion/ej2-react-buttons';
import * as React from 'react';
import { data } from './datasource';

function App() {
  let grid;
  const loadData = () => {
    grid.showSpinner();
    setTimeout(() => {
      grid.dataSource = data;
      grid.hideSpinner();
    }, 1000);
  }

  const showhideSpinner = (args) => {
    if (args.currentTarget.id === 'showButton') {
      grid.showSpinner();
    } else {
      grid.hideSpinner();
    }
  }
  return <div>
    <ButtonComponent id='loadButton' cssClass='e-outline' onClick={loadData}>Load Data</ButtonComponent>
    <ButtonComponent id='showButton' cssClass='e-outline' style={{ marginLeft: "5px" }} onClick={showhideSpinner}>Show Spinner</ButtonComponent>
    <ButtonComponent id='hideButton' cssClass='e-outline' style={{ marginLeft: "5px" }} onClick={showhideSpinner}>Hide Spinner</ButtonComponent>
    <GridComponent ref={g => { grid = g }} height='320' allowPaging={true}>
      <ColumnsDirective>
        <ColumnDirective field='OrderID' headerText='Order ID' isPrimaryKey={true} width='120' textAlign='Right'></ColumnDirective>
        <ColumnDirective field='CustomerID' headerText='Customer ID' width='160'></ColumnDirective>
        <ColumnDirective field='ProductName' headerText='Product Name' width='130' textAlign='Right' />
        <ColumnDirective field='Quantity' headerText='Quantity' width='120' />
      </ColumnsDirective>
      <Inject services={[Page]} />
    </GridComponent>
  </div>
}
export default App;
import { ColumnDirective, ColumnsDirective, GridComponent, Inject, Page } from '@syncfusion/ej2-react-grids';
import { ButtonComponent } from '@syncfusion/ej2-react-buttons';
import * as React from 'react';
import { data } from './datasource';

function App() {
  let grid: GridComponent | null;
  const loadData = () => {
    (grid as GridComponent).showSpinner();
    setTimeout(() => {
      (grid as GridComponent).dataSource = data;
      (grid as GridComponent).hideSpinner();
    }, 1000);
  }

  const showhideSpinner = (args: MouseEvent) => {
    if ((args.currentTarget as HTMLElement).id === 'showButton') {
      (grid as GridComponent).showSpinner();
    } else {
      (grid as GridComponent).hideSpinner();
    }
  }
  return <div>
    <ButtonComponent id='loadButton' cssClass='e-outline' onClick={loadData}>Load Data</ButtonComponent>
    <ButtonComponent id='showButton' cssClass='e-outline' style={{ marginLeft: "5px" }} onClick={showhideSpinner}>Show Spinner</ButtonComponent>
    <ButtonComponent id='hideButton' cssClass='e-outline' style={{ marginLeft: "5px" }} onClick={showhideSpinner}>Hide Spinner</ButtonComponent>
    <GridComponent ref={g => { grid = g }} height='320px' allowPaging={true}>
      <ColumnsDirective>
        <ColumnDirective field='OrderID' headerText='Order ID' isPrimaryKey={true} width='120' textAlign='Right'></ColumnDirective>
        <ColumnDirective field='CustomerID' headerText='Customer ID' width='160'></ColumnDirective>
        <ColumnDirective field='ProductName' headerText='Product Name' width='130' textAlign='Right' />
        <ColumnDirective field='Quantity' headerText='Quantity' width='120' />
      </ColumnsDirective>
      <Inject services={[Page]} />
    </GridComponent>
  </div>
}
export default App;
export let data = createLazyLoadData();
function createLazyLoadData() {
    let lazyLoadData = [];
    let customerid = [
        "VINET",
        "TOMSP",
        "HANAR",
        "VICTE",
        "SUPRD",
        "HANAR",
        "CHOPS",
        "RICSU",
        "WELLI",
        "HILAA",
        "ERNSH",
        "CENTC",
        "OTTIK",
        "QUEDE",
        "RATTC",
        "ERNSH",
        "FOLKO",
        "BLONP",
        "WARTH",
        "FRANK",
        "GROSR",
        "WHITC",
        "WARTH",
        "SPLIR",
        "RATTC",
        "QUICK",
        "VINET",
        "MAGAA",
        "TORTU",
        "MORGK",
        "BERGS",
        "LEHMS",
        "BERGS",
        "ROMEY",
        "ROMEY",
        "LILAS",
        "LEHMS",
        "QUICK",
        "QUICK",
        "RICAR",
        "REGGC",
        "BSBEV",
        "COMMI",
        "QUEDE",
        "TRADH",
        "TORTU",
        "RATTC",
        "VINET",
        "LILAS",
        "BLONP",
        "HUNGO",
        "RICAR",
        "MAGAA",
        "WANDK",
        "SUPRD",
        "GODOS",
        "TORTU",
        "OLDWO",
        "ROMEY",
        "LONEP",
        "ANATR",
        "HUNGO",
        "THEBI",
        "DUMON",
        "WANDK",
        "QUICK",
        "RATTC",
        "ISLAT",
        "RATTC",
        "LONEP",
        "ISLAT",
        "TORTU",
        "WARTH",
        "ISLAT",
        "PERIC",
        "KOENE",
        "SAVEA",
        "KOENE",
        "BOLID",
        "FOLKO",
        "FURIB",
        "SPLIR",
        "LILAS",
        "BONAP",
        "MEREP",
        "WARTH",
        "VICTE",
        "HUNGO",
        "PRINI",
        "FRANK",
        "OLDWO",
        "MEREP",
        "BONAP",
        "SIMOB",
        "FRANK",
        "LEHMS",
        "WHITC",
        "QUICK",
        "RATTC",
        "FAMIA"
    ];
    let product = [
        "Chai",
        "Chang",
        "Aniseed Syrup",
        "Chef Anton's Cajun Seasoning",
        "Chef Anton's Gumbo Mix",
        "Grandma's Boysenberry Spread",
        "Uncle Bob's Organic Dried Pears",
        "Northwoods Cranberry Sauce",
        "Mishi Kobe Niku",
        "Ikura",
        "Queso Cabrales",
        "Queso Manchego La Pastora",
        "Konbu",
        "Tofu",
        "Genen Shouyu",
        "Pavlova",
        "Alice Mutton",
        "Carnarvon Tigers",
        "Teatime Chocolate Biscuits",
        "Sir Rodney's Marmalade",
        "Sir Rodney's Scones",
        "Gustaf's Knäckebröd",
        "Tunnbröd",
        "Guaraná Fantástica",
        "NuNuCa Nuß-Nougat-Creme",
        "Gumbär Gummibärchen",
        "Schoggi Schokolade",
        "Rössle Sauerkraut",
        "Thüringer Rostbratwurst",
        "Nord-Ost Matjeshering",
        "Gorgonzola Telino",
        "Mascarpone Fabioli",
        "Geitost",
        "Sasquatch Ale",
        "Steeleye Stout",
        "Inlagd Sill",
        "Gravad lax",
        "Côte de Blaye",
        "Chartreuse verte",
        "Boston Crab Meat",
        "Jack's New England Clam Chowder",
        "Singaporean Hokkien Fried Mee",
        "Ipoh Coffee",
        "Gula Malacca",
        "Rogede sild",
        "Spegesild",
        "Zaanse koeken",
        "Chocolade",
        "Maxilaku",
        "Valkoinen suklaa",
        "Manjimup Dried Apples",
        "Filo Mix",
        "Perth Pasties",
        "Tourtière",
        "Pâté chinois",
        "Gnocchi di nonna Alice",
        "Ravioli Angelo",
        "Escargots de Bourgogne",
        "Raclette Courdavault",
        "Camembert Pierrot",
        "Sirop d'érable",
        "Tarte au sucre",
        "Vegie-spread",
        "Wimmers gute Semmelknödel",
        "Louisiana Fiery Hot Pepper Sauce",
        "Louisiana Hot Spiced Okra",
        "Laughing Lumberjack Lager",
        "Scottish Longbreads",
        "Gudbrandsdalsost",
        "Outback Lager",
        "Flotemysost",
        "Mozzarella di Giovanni",
        "Röd Kaviar",
        "Longlife Tofu",
        "Rhönbräu Klosterbier",
        "Lakkalikööri",
        "Original Frankfurter grüne Soße"
    ];
    let customername = [
        "Maria",
        "Ana Trujillo",
        "Antonio Moreno",
        "Thomas Hardy",
        "Christina Berglund",
        "Hanna Moos",
        "Frédérique Citeaux",
        "Martín Sommer",
        "Laurence Lebihan",
        "Elizabeth Lincoln",
        "Victoria Ashworth",
        "Patricio Simpson",
        "Francisco Chang",
        "Yang Wang",
        "Pedro Afonso",
        "Elizabeth Brown",
        "Sven Ottlieb",
        "Janine Labrune",
        "Ann Devon",
        "Roland Mendel",
        "Aria Cruz",
        "Diego Roel",
        "Martine Rancé",
        "Maria Larsson",
        "Peter Franken",
        "Carine Schmitt",
        "Paolo Accorti",
        "Lino Rodriguez",
        "Eduardo Saavedra",
        "José Pedro Freyre",
        "André Fonseca",
        "Howard Snyder",
        "Manuel Pereira",
        "Mario Pontes",
        "Carlos Hernández",
        "Yoshi Latimer",
        "Patricia McKenna",
        "Helen Bennett",
        "Philip Cramer",
        "Daniel Tonini",
        "Annette Roulet",
        "Yoshi Tannamuri",
        "John Steel",
        "Renate Messner",
        "Jaime Yorres",
        "Carlos González",
        "Felipe Izquierdo",
        "Fran Wilson",
        "Giovanni Rovelli",
        "Catherine Dewey",
        "Jean Fresnière",
        "Alexander Feuer",
        "Simon Crowther",
        "Yvonne Moncada",
        "Rene Phillips",
        "Henriette Pfalzheim",
        "Marie Bertrand",
        "Guillermo Fernández",
        "Georg Pipps",
        "Isabel de Castro",
        "Bernardo Batista",
        "Lúcia Carvalho",
        "Horst Kloss",
        "Sergio Gutiérrez",
        "Paula Wilson",
        "Maurizio Moroni",
        "Janete Limeira",
        "Michael Holz",
        "Alejandra Camino",
        "Jonas Bergulfsen",
        "Jose Pavarotti",
        "Hari Kumar",
        "Jytte Petersen",
        "Dominique Perrier",
        "Art Braunschweiger",
        "Pascale Cartrain",
        "Liz Nixon",
        "Liu Wong",
        "Karin Josephs",
        "Miguel Angel Paolino",
        "Anabela Domingues",
        "Helvetius Nagy",
        "Palle Ibsen",
        "Mary Saveley",
        "Paul Henriot",
        "Rita Müller",
        "Pirkko Koskitalo",
        "Paula Parente",
        "Karl Jablonski",
        "Matti Karttunen",
        "Zbyszek Piestrzeniewicz"
    ];
    let customeraddress = [
        "507 - 20th Ave. E.\r\nApt. 2A",
        "908 W. Capital Way",
        "722 Moss Bay Blvd.",
        "4110 Old Redmond Rd.",
        "14 Garrett Hill",
        "Coventry House\r\nMiner Rd.",
        "Edgeham Hollow\r\nWinchester Way",
        "4726 - 11th Ave. N.E.",
        "7 Houndstooth Rd.",
        "59 rue de l'Abbaye",
        "Luisenstr. 48",
        "908 W. Capital Way",
        "722 Moss Bay Blvd.",
        "4110 Old Redmond Rd.",
        "14 Garrett Hill",
        "Coventry House\r\nMiner Rd.",
        "Edgeham Hollow\r\nWinchester Way",
        "7 Houndstooth Rd.",
        "2817 Milton Dr.",
        "Kirchgasse 6",
        "Sierras de Granada 9993",
        "Mehrheimerstr. 369",
        "Rua da Panificadora, 12",
        "2817 Milton Dr.",
        "Mehrheimerstr. 369"
    ];
    let quantityperunit = [
        "10 boxes x 20 bags",
        "24 - 12 oz bottles",
        "12 - 550 ml bottles",
        "48 - 6 oz jars",
        "36 boxes",
        "12 - 8 oz jars",
        "12 - 1 lb pkgs.",
        "12 - 12 oz jars",
        "18 - 500 g pkgs.",
        "12 - 200 ml jars",
        "1 kg pkg.",
        "10 - 500 g pkgs.",
        "2 kg box",
        "40 - 100 g pkgs.",
        "24 - 250 ml bottles",
        "32 - 500 g boxes",
        "20 - 1 kg tins",
        "16 kg pkg.",
        "10 boxes x 12 pieces",
        "30 gift boxes",
        "24 pkgs. x 4 pieces",
        "24 - 500 g pkgs.",
        "12 - 250 g pkgs.",
        "12 - 355 ml cans",
        "20 - 450 g glasses",
        "100 - 250 g bags"
    ];
    let orderID = 10248;
    let k = 1;
    for (let i = 0; i < 1000; i++) {
        k = k > 9 ? 1 : k;
        lazyLoadData.push({
            OrderID: orderID + i,
            CustomerID: customerid[Math.floor(Math.random() * customerid.length)],
            CustomerName: customername[Math.floor(Math.random() * customername.length)],
            CustomerAddress: customeraddress[Math.floor(Math.random() * customeraddress.length)],
            ProductName: product[Math.floor(Math.random() * product.length)],
            ProductID: i,
            Quantity: quantityperunit[Math.floor(Math.random() * quantityperunit.length)],
            Id: k
        });
        k++;
    }
    return lazyLoadData;
}
export let data: Object[] = createLazyLoadData();

function createLazyLoadData() {
  let lazyLoadData: Object[] = [];
  let customerid: string[] = [
    "VINET",
    "TOMSP",
    "HANAR",
    "VICTE",
    "SUPRD",
    "HANAR",
    "CHOPS",
    "RICSU",
    "WELLI",
    "HILAA",
    "ERNSH",
    "CENTC",
    "OTTIK",
    "QUEDE",
    "RATTC",
    "ERNSH",
    "FOLKO",
    "BLONP",
    "WARTH",
    "FRANK",
    "GROSR",
    "WHITC",
    "WARTH",
    "SPLIR",
    "RATTC",
    "QUICK",
    "VINET",
    "MAGAA",
    "TORTU",
    "MORGK",
    "BERGS",
    "LEHMS",
    "BERGS",
    "ROMEY",
    "ROMEY",
    "LILAS",
    "LEHMS",
    "QUICK",
    "QUICK",
    "RICAR",
    "REGGC",
    "BSBEV",
    "COMMI",
    "QUEDE",
    "TRADH",
    "TORTU",
    "RATTC",
    "VINET",
    "LILAS",
    "BLONP",
    "HUNGO",
    "RICAR",
    "MAGAA",
    "WANDK",
    "SUPRD",
    "GODOS",
    "TORTU",
    "OLDWO",
    "ROMEY",
    "LONEP",
    "ANATR",
    "HUNGO",
    "THEBI",
    "DUMON",
    "WANDK",
    "QUICK",
    "RATTC",
    "ISLAT",
    "RATTC",
    "LONEP",
    "ISLAT",
    "TORTU",
    "WARTH",
    "ISLAT",
    "PERIC",
    "KOENE",
    "SAVEA",
    "KOENE",
    "BOLID",
    "FOLKO",
    "FURIB",
    "SPLIR",
    "LILAS",
    "BONAP",
    "MEREP",
    "WARTH",
    "VICTE",
    "HUNGO",
    "PRINI",
    "FRANK",
    "OLDWO",
    "MEREP",
    "BONAP",
    "SIMOB",
    "FRANK",
    "LEHMS",
    "WHITC",
    "QUICK",
    "RATTC",
    "FAMIA"
  ];

  let product: string[] = [
    "Chai",
    "Chang",
    "Aniseed Syrup",
    "Chef Anton's Cajun Seasoning",
    "Chef Anton's Gumbo Mix",
    "Grandma's Boysenberry Spread",
    "Uncle Bob's Organic Dried Pears",
    "Northwoods Cranberry Sauce",
    "Mishi Kobe Niku",
    "Ikura",
    "Queso Cabrales",
    "Queso Manchego La Pastora",
    "Konbu",
    "Tofu",
    "Genen Shouyu",
    "Pavlova",
    "Alice Mutton",
    "Carnarvon Tigers",
    "Teatime Chocolate Biscuits",
    "Sir Rodney's Marmalade",
    "Sir Rodney's Scones",
    "Gustaf's Knäckebröd",
    "Tunnbröd",
    "Guaraná Fantástica",
    "NuNuCa Nuß-Nougat-Creme",
    "Gumbär Gummibärchen",
    "Schoggi Schokolade",
    "Rössle Sauerkraut",
    "Thüringer Rostbratwurst",
    "Nord-Ost Matjeshering",
    "Gorgonzola Telino",
    "Mascarpone Fabioli",
    "Geitost",
    "Sasquatch Ale",
    "Steeleye Stout",
    "Inlagd Sill",
    "Gravad lax",
    "Côte de Blaye",
    "Chartreuse verte",
    "Boston Crab Meat",
    "Jack's New England Clam Chowder",
    "Singaporean Hokkien Fried Mee",
    "Ipoh Coffee",
    "Gula Malacca",
    "Rogede sild",
    "Spegesild",
    "Zaanse koeken",
    "Chocolade",
    "Maxilaku",
    "Valkoinen suklaa",
    "Manjimup Dried Apples",
    "Filo Mix",
    "Perth Pasties",
    "Tourtière",
    "Pâté chinois",
    "Gnocchi di nonna Alice",
    "Ravioli Angelo",
    "Escargots de Bourgogne",
    "Raclette Courdavault",
    "Camembert Pierrot",
    "Sirop d'érable",
    "Tarte au sucre",
    "Vegie-spread",
    "Wimmers gute Semmelknödel",
    "Louisiana Fiery Hot Pepper Sauce",
    "Louisiana Hot Spiced Okra",
    "Laughing Lumberjack Lager",
    "Scottish Longbreads",
    "Gudbrandsdalsost",
    "Outback Lager",
    "Flotemysost",
    "Mozzarella di Giovanni",
    "Röd Kaviar",
    "Longlife Tofu",
    "Rhönbräu Klosterbier",
    "Lakkalikööri",
    "Original Frankfurter grüne Soße"
  ];

  let customername: string[] = [
    "Maria",
    "Ana Trujillo",
    "Antonio Moreno",
    "Thomas Hardy",
    "Christina Berglund",
    "Hanna Moos",
    "Frédérique Citeaux",
    "Martín Sommer",
    "Laurence Lebihan",
    "Elizabeth Lincoln",
    "Victoria Ashworth",
    "Patricio Simpson",
    "Francisco Chang",
    "Yang Wang",
    "Pedro Afonso",
    "Elizabeth Brown",
    "Sven Ottlieb",
    "Janine Labrune",
    "Ann Devon",
    "Roland Mendel",
    "Aria Cruz",
    "Diego Roel",
    "Martine Rancé",
    "Maria Larsson",
    "Peter Franken",
    "Carine Schmitt",
    "Paolo Accorti",
    "Lino Rodriguez",
    "Eduardo Saavedra",
    "José Pedro Freyre",
    "André Fonseca",
    "Howard Snyder",
    "Manuel Pereira",
    "Mario Pontes",
    "Carlos Hernández",
    "Yoshi Latimer",
    "Patricia McKenna",
    "Helen Bennett",
    "Philip Cramer",
    "Daniel Tonini",
    "Annette Roulet",
    "Yoshi Tannamuri",
    "John Steel",
    "Renate Messner",
    "Jaime Yorres",
    "Carlos González",
    "Felipe Izquierdo",
    "Fran Wilson",
    "Giovanni Rovelli",
    "Catherine Dewey",
    "Jean Fresnière",
    "Alexander Feuer",
    "Simon Crowther",
    "Yvonne Moncada",
    "Rene Phillips",
    "Henriette Pfalzheim",
    "Marie Bertrand",
    "Guillermo Fernández",
    "Georg Pipps",
    "Isabel de Castro",
    "Bernardo Batista",
    "Lúcia Carvalho",
    "Horst Kloss",
    "Sergio Gutiérrez",
    "Paula Wilson",
    "Maurizio Moroni",
    "Janete Limeira",
    "Michael Holz",
    "Alejandra Camino",
    "Jonas Bergulfsen",
    "Jose Pavarotti",
    "Hari Kumar",
    "Jytte Petersen",
    "Dominique Perrier",
    "Art Braunschweiger",
    "Pascale Cartrain",
    "Liz Nixon",
    "Liu Wong",
    "Karin Josephs",
    "Miguel Angel Paolino",
    "Anabela Domingues",
    "Helvetius Nagy",
    "Palle Ibsen",
    "Mary Saveley",
    "Paul Henriot",
    "Rita Müller",
    "Pirkko Koskitalo",
    "Paula Parente",
    "Karl Jablonski",
    "Matti Karttunen",
    "Zbyszek Piestrzeniewicz"
  ];

  let customeraddress: string[] = [
    "507 - 20th Ave. E.\r\nApt. 2A",
    "908 W. Capital Way",
    "722 Moss Bay Blvd.",
    "4110 Old Redmond Rd.",
    "14 Garrett Hill",
    "Coventry House\r\nMiner Rd.",
    "Edgeham Hollow\r\nWinchester Way",
    "4726 - 11th Ave. N.E.",
    "7 Houndstooth Rd.",
    "59 rue de l'Abbaye",
    "Luisenstr. 48",
    "908 W. Capital Way",
    "722 Moss Bay Blvd.",
    "4110 Old Redmond Rd.",
    "14 Garrett Hill",
    "Coventry House\r\nMiner Rd.",
    "Edgeham Hollow\r\nWinchester Way",
    "7 Houndstooth Rd.",
    "2817 Milton Dr.",
    "Kirchgasse 6",
    "Sierras de Granada 9993",
    "Mehrheimerstr. 369",
    "Rua da Panificadora, 12",
    "2817 Milton Dr.",
    "Mehrheimerstr. 369"
  ];

  let quantityperunit: string[] = [
    "10 boxes x 20 bags",
    "24 - 12 oz bottles",
    "12 - 550 ml bottles",
    "48 - 6 oz jars",
    "36 boxes",
    "12 - 8 oz jars",
    "12 - 1 lb pkgs.",
    "12 - 12 oz jars",
    "18 - 500 g pkgs.",
    "12 - 200 ml jars",
    "1 kg pkg.",
    "10 - 500 g pkgs.",
    "2 kg box",
    "40 - 100 g pkgs.",
    "24 - 250 ml bottles",
    "32 - 500 g boxes",
    "20 - 1 kg tins",
    "16 kg pkg.",
    "10 boxes x 12 pieces",
    "30 gift boxes",
    "24 pkgs. x 4 pieces",
    "24 - 500 g pkgs.",
    "12 - 250 g pkgs.",
    "12 - 355 ml cans",
    "20 - 450 g glasses",
    "100 - 250 g bags"
  ];

  let orderID: number = 10248;
  let k: number = 1;
  for (let i: number = 0; i < 1000; i++) {
    k = k > 9 ? 1 : k;
    lazyLoadData.push({
      OrderID: orderID + i,
      CustomerID: customerid[Math.floor(Math.random() * customerid.length)],
      CustomerName:
        customername[Math.floor(Math.random() * customername.length)],
      CustomerAddress:
        customeraddress[Math.floor(Math.random() * customeraddress.length)],
      ProductName: product[Math.floor(Math.random() * product.length)],
      ProductID: i,
      Quantity:
        quantityperunit[Math.floor(Math.random() * quantityperunit.length)],
      Id: k
    });
    k++;
  }
  return lazyLoadData;
}

Immutable mode 

Immutable mode in the Syncfusion Grid is designed to optimize re-rendering performance by utilizing the object reference and deep compare concept. This mode ensures that when performing Grid actions, only the modified or newly added rows are re-rendered, preventing unnecessary re-rendering of unchanged rows.

To enable this feature, you need to set the enableImmutableMode property as true.

If immutable mode is enabled, when the datasource changes, only newly added rows are regenerated or reused. Consequently, the grid’s queryCellInfo and rowDataBound events trigger only for newly generated rows, not for existing rows.

If immutable mode is not enabled, both newly added rows and existing rows are regenerated or reused when the datasource changes. As a result, the rowDataBound and queryCellInfo events trigger for both newly added and existing rows.

This feature uses the primary key value for data comparison. So, you need to provide the isPrimaryKey column.

The following example demonstrates how to enable immutable mode in an React component. When add, delete, or update actions are performed, existing rows are not regenerated or reused, ensuring efficient rendering of only the modified or newly added rows:

import { ColumnDirective, ColumnsDirective, GridComponent, Inject, Page } from '@syncfusion/ej2-react-grids';
import { ButtonComponent } from '@syncfusion/ej2-react-buttons';
import React, { useState } from 'react';
import { data } from './datasource';

function App() {
  const pageSettings = { pageSize: 50 };
  const [rowData, setRowData] = useState(data);
  const selectionSettings = {type: 'Multiple'};
  const [message, setMessage] = useState('')
  let immutableGrid;
  const queryCellInfo = (args) => {
    if (args.column.field === 'ShipName' && args.data.ShipName === "Gems Chevalier") {
      args.cell.style.backgroundColor = 'rgb(210, 226, 129)';
    }
  }
  const rowDataBound = (args) => {
    args.row.style.backgroundColor = args.data.isNewlyAdded ? '' : ' rgb(208, 255, 255)';
  }
  const addTopEvent = () => {
    immutableGrid.getAllDataRows().forEach(row => {
      row.style.backgroundColor = "rgb(208, 255, 255)";
    });
    let count = 0;
    if (count < 1) {
      let newRowData = [];
      let addedRecords = {
        'OrderID': generateOrderId(),
        'CustomerID': generateCustomerId(),
        'ShipCity': generateShipCity(),
        'Freight': generateFreight(),
        'ShipName': generateShipName(),
        'isNewlyAdded': true
      };
      newRowData.push(addedRecords);
      setRowData(([...newRowData, ...rowData]));
      count++;
      setMessage(`${count} rows rendered after performing the add action`);
    }
  }
  const deleteEvent = () => {
    let count = 0;
    if (count < 1 && (rowData).length > 0) {
      setRowData((rowData).slice(1));
      count++;
      setMessage(`${count} rows deleted after performing delete action`);
    }
  }
  const updateEvent =() => {
    let count = 0;
    let newRowData = rowData.map((row) => {
      if (row.ShipName === 'Bueno Foods') {
        count++;
        return { ...row, 'ShipName': "Gems Chevalier" };
      } else {
        return row;
      }
    });
    setRowData(newRowData);
    setMessage(` ${count} rows updated after performing update action`);
  }

  const generateOrderId = () => {
    return Math.floor(10000 + Math.random() * 90000);
  }

  const generateCustomerId =() => {
    const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    let result = '';
    for (let i = 0; i < 5; i++) {
      result += characters.charAt(Math.floor(Math.random() * characters.length));
    }
    return result;
  }

  const generateShipCity = () => {
    const cities = ['London', 'Paris', 'New York', 'Tokyo', 'Berlin'];
    return cities[Math.floor(Math.random() * cities.length)];
  }

  const generateFreight =() => {
    const randomValue = Math.random() * 100;
    return parseFloat(randomValue.toFixed(2));
  }

  const generateShipName =() => {
    const names = ['Que Delícia', 'Bueno Foods', 'Island Trading', 'Laughing Bacchus Winecellars'];
    return names[Math.floor(Math.random() * names.length)];
  }
  return <div>
              <ButtonComponent cssClass='e-info' onClick={addTopEvent}>Add rows data</ButtonComponent>
              <ButtonComponent cssClass='e-info' onClick={deleteEvent}>Delete rows</ButtonComponent>
              <ButtonComponent cssClass='e-info' onClick={updateEvent}>Update Freight Data</ButtonComponent>
              <div id='message'>{message}</div>
              <GridComponent ref={immutable => { immutableGrid = immutable }} dataSource={rowData} height='250' enableImmutableMode={true} allowPaging={true} pageSettings={pageSettings} selectionSettings={selectionSettings} rowDataBound={rowDataBound} queryCellInfo={queryCellInfo}>
                <ColumnsDirective>
                  <ColumnDirective field='OrderID' headerText='Order ID' isPrimaryKey={true} width='120' textAlign='Right'></ColumnDirective>
                  <ColumnDirective field='CustomerID' headerText='Customer ID' width='160'></ColumnDirective>
                  <ColumnDirective field='Freight' headerText='Freight' width='130' textAlign='Right' />
                  <ColumnDirective field='ShipName' headerText='Ship Name' width='120' />
                </ColumnsDirective>
                <Inject services={[Page]} />
              </GridComponent>
            </div>
}
export default App;
import { ColumnDirective, ColumnsDirective, GridComponent, Inject, Page, RowDataBoundEventArgs } from '@syncfusion/ej2-react-grids';
import { ButtonComponent } from '@syncfusion/ej2-react-buttons';
import React, { useState } from 'react';
import { data } from './datasource';

interface CustomRowDataBoundEventArgs extends RowDataBoundEventArgs {
  column: {
    field: string;
  };
  cell: HTMLElement;
  data: DataType;
}

interface DataType {
  OrderID: number;
  CustomerID: string;
  Freight: number;
  ShipName: string;
  ShipCity: string;
  isNewlyAdded: boolean;
}

function App() {
  const pageSettings: object = { pageSize: 50 };
  const [rowData, setRowData] = useState<DataType[]>(data)
  const selectionSettings: object = {type: 'Multiple'};
  const [message, setMessage] = useState('')
  let immutableGrid: GridComponent | null;
  const queryCellInfo = (args: CustomRowDataBoundEventArgs) => {
    if (args.column.field === 'ShipName' && args.data.ShipName === "Gems Chevalier") {
      (args.cell as HTMLElement).style.backgroundColor = 'rgb(210, 226, 129)';
    }
  }
  const rowDataBound = (args: RowDataBoundEventArgs) => {
    (args.row as HTMLElement).style.backgroundColor = (args.data as DataType).isNewlyAdded ? '' : ' rgb(208, 255, 255)';
  }
  const addTopEvent = () => {
    (immutableGrid as GridComponent).getAllDataRows().forEach(row => {
      (row as HTMLElement).style.backgroundColor = "rgb(208, 255, 255)";
    });
    let count = 0;
    if (count < 1) {
      let newRowData: object[] = [];
      let addedRecords: object = {
        'OrderID': generateOrderId(),
        'CustomerID': generateCustomerId(),
        'ShipCity': generateShipCity(),
        'Freight': generateFreight(),
        'ShipName': generateShipName(),
        'isNewlyAdded': true
      };
      newRowData.push(addedRecords);
      setRowData(([...newRowData, ...rowData as DataType[]] as DataType[]));
      count++;
      setMessage(`${count} rows rendered after performing the add action`);
    }
  }
  const deleteEvent = () => {
    let count = 0;
    if (count < 1 && (rowData as DataType[]).length > 0) {
      setRowData((rowData as DataType[]).slice(1));
      count++;
      setMessage(`${count} rows deleted after performing delete action`);
    }
  }
  const updateEvent =() => {
    let count = 0;
    let newRowData = (rowData as any).map((row: any) => {
      if (row.ShipName === 'Bueno Foods') {
        count++;
        return { ...row, 'ShipName': "Gems Chevalier" };
      } else {
        return row;
      }
    });
    setRowData(newRowData);
    setMessage(` ${count} rows updated after performing update action`);
  }

  const generateOrderId = () => {
    return Math.floor(10000 + Math.random() * 90000);
  }

  const generateCustomerId =() => {
    const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    let result = '';
    for (let i = 0; i < 5; i++) {
      result += characters.charAt(Math.floor(Math.random() * characters.length));
    }
    return result;
  }

  const generateShipCity = () => {
    const cities = ['London', 'Paris', 'New York', 'Tokyo', 'Berlin'];
    return cities[Math.floor(Math.random() * cities.length)];
  }

  const generateFreight =() => {
    const randomValue = Math.random() * 100;
    return parseFloat(randomValue.toFixed(2));
  }

  const generateShipName =() => {
    const names = ['Que Delícia', 'Bueno Foods', 'Island Trading', 'Laughing Bacchus Winecellars'];
    return names[Math.floor(Math.random() * names.length)];
  }
  return <div>
              <ButtonComponent cssClass='e-info' onClick={addTopEvent}>Add rows data</ButtonComponent>
              <ButtonComponent cssClass='e-info' onClick={deleteEvent}>Delete rows</ButtonComponent>
              <ButtonComponent cssClass='e-info' onClick={updateEvent}>Update Freight Data</ButtonComponent>
              <div id='message'>{message}</div>
              <GridComponent ref={immutable => { immutableGrid = immutable }} dataSource={rowData } height='250' enableImmutableMode={true} allowPaging={true} pageSettings={pageSettings} selectionSettings={selectionSettings} rowDataBound={rowDataBound} queryCellInfo={queryCellInfo}>
                <ColumnsDirective>
                  <ColumnDirective field='OrderID' headerText='Order ID' isPrimaryKey={true} width='120' textAlign='Right'></ColumnDirective>
                  <ColumnDirective field='CustomerID' headerText='Customer ID' width='160'></ColumnDirective>
                  <ColumnDirective field='Freight' headerText='Freight' width='130' textAlign='Right' />
                  <ColumnDirective field='ShipName' headerText='Ship Name' width='120' />
                </ColumnsDirective>
                <Inject services={[Page]} />
              </GridComponent>
            </div>
}
export default App;
export let data = createLazyLoadData();
function createLazyLoadData() {
    let lazyLoadData = [];
    let customerid = [
        "VINET",
        "TOMSP",
        "HANAR",
        "VICTE",
        "SUPRD",
        "HANAR",
        "CHOPS",
        "RICSU",
        "WELLI",
        "HILAA",
        "ERNSH",
        "CENTC",
        "OTTIK",
        "QUEDE",
        "RATTC",
        "ERNSH",
        "FOLKO",
        "BLONP",
        "WARTH",
        "FRANK",
        "GROSR",
        "WHITC",
        "WARTH",
        "SPLIR",
        "RATTC",
        "QUICK",
        "VINET",
        "MAGAA",
        "TORTU",
        "MORGK",
        "BERGS",
        "LEHMS",
        "BERGS",
        "ROMEY",
        "ROMEY",
        "LILAS",
        "LEHMS",
        "QUICK",
        "QUICK",
        "RICAR",
        "REGGC",
        "BSBEV",
        "COMMI",
        "QUEDE",
        "TRADH",
        "TORTU",
        "RATTC",
        "VINET",
        "LILAS",
        "BLONP",
        "HUNGO",
        "RICAR",
        "MAGAA",
        "WANDK",
        "SUPRD",
        "GODOS",
        "TORTU",
        "OLDWO",
        "ROMEY",
        "LONEP",
        "ANATR",
        "HUNGO",
        "THEBI",
        "DUMON",
        "WANDK",
        "QUICK",
        "RATTC",
        "ISLAT",
        "RATTC",
        "LONEP",
        "ISLAT",
        "TORTU",
        "WARTH",
        "ISLAT",
        "PERIC",
        "KOENE",
        "SAVEA",
        "KOENE",
        "BOLID",
        "FOLKO",
        "FURIB",
        "SPLIR",
        "LILAS",
        "BONAP",
        "MEREP",
        "WARTH",
        "VICTE",
        "HUNGO",
        "PRINI",
        "FRANK",
        "OLDWO",
        "MEREP",
        "BONAP",
        "SIMOB",
        "FRANK",
        "LEHMS",
        "WHITC",
        "QUICK",
        "RATTC",
        "FAMIA"
    ];
    let product = [
        "Chai",
        "Chang",
        "Aniseed Syrup",
        "Chef Anton's Cajun Seasoning",
        "Chef Anton's Gumbo Mix",
        "Grandma's Boysenberry Spread",
        "Uncle Bob's Organic Dried Pears",
        "Northwoods Cranberry Sauce",
        "Mishi Kobe Niku",
        "Ikura",
        "Queso Cabrales",
        "Queso Manchego La Pastora",
        "Konbu",
        "Tofu",
        "Genen Shouyu",
        "Pavlova",
        "Alice Mutton",
        "Carnarvon Tigers",
        "Teatime Chocolate Biscuits",
        "Sir Rodney's Marmalade",
        "Sir Rodney's Scones",
        "Gustaf's Knäckebröd",
        "Tunnbröd",
        "Guaraná Fantástica",
        "NuNuCa Nuß-Nougat-Creme",
        "Gumbär Gummibärchen",
        "Schoggi Schokolade",
        "Rössle Sauerkraut",
        "Thüringer Rostbratwurst",
        "Nord-Ost Matjeshering",
        "Gorgonzola Telino",
        "Mascarpone Fabioli",
        "Geitost",
        "Sasquatch Ale",
        "Steeleye Stout",
        "Inlagd Sill",
        "Gravad lax",
        "Côte de Blaye",
        "Chartreuse verte",
        "Boston Crab Meat",
        "Jack's New England Clam Chowder",
        "Singaporean Hokkien Fried Mee",
        "Ipoh Coffee",
        "Gula Malacca",
        "Rogede sild",
        "Spegesild",
        "Zaanse koeken",
        "Chocolade",
        "Maxilaku",
        "Valkoinen suklaa",
        "Manjimup Dried Apples",
        "Filo Mix",
        "Perth Pasties",
        "Tourtière",
        "Pâté chinois",
        "Gnocchi di nonna Alice",
        "Ravioli Angelo",
        "Escargots de Bourgogne",
        "Raclette Courdavault",
        "Camembert Pierrot",
        "Sirop d'érable",
        "Tarte au sucre",
        "Vegie-spread",
        "Wimmers gute Semmelknödel",
        "Louisiana Fiery Hot Pepper Sauce",
        "Louisiana Hot Spiced Okra",
        "Laughing Lumberjack Lager",
        "Scottish Longbreads",
        "Gudbrandsdalsost",
        "Outback Lager",
        "Flotemysost",
        "Mozzarella di Giovanni",
        "Röd Kaviar",
        "Longlife Tofu",
        "Rhönbräu Klosterbier",
        "Lakkalikööri",
        "Original Frankfurter grüne Soße"
    ];
    let customername = [
        "Maria",
        "Ana Trujillo",
        "Antonio Moreno",
        "Thomas Hardy",
        "Christina Berglund",
        "Hanna Moos",
        "Frédérique Citeaux",
        "Martín Sommer",
        "Laurence Lebihan",
        "Elizabeth Lincoln",
        "Victoria Ashworth",
        "Patricio Simpson",
        "Francisco Chang",
        "Yang Wang",
        "Pedro Afonso",
        "Elizabeth Brown",
        "Sven Ottlieb",
        "Janine Labrune",
        "Ann Devon",
        "Roland Mendel",
        "Aria Cruz",
        "Diego Roel",
        "Martine Rancé",
        "Maria Larsson",
        "Peter Franken",
        "Carine Schmitt",
        "Paolo Accorti",
        "Lino Rodriguez",
        "Eduardo Saavedra",
        "José Pedro Freyre",
        "André Fonseca",
        "Howard Snyder",
        "Manuel Pereira",
        "Mario Pontes",
        "Carlos Hernández",
        "Yoshi Latimer",
        "Patricia McKenna",
        "Helen Bennett",
        "Philip Cramer",
        "Daniel Tonini",
        "Annette Roulet",
        "Yoshi Tannamuri",
        "John Steel",
        "Renate Messner",
        "Jaime Yorres",
        "Carlos González",
        "Felipe Izquierdo",
        "Fran Wilson",
        "Giovanni Rovelli",
        "Catherine Dewey",
        "Jean Fresnière",
        "Alexander Feuer",
        "Simon Crowther",
        "Yvonne Moncada",
        "Rene Phillips",
        "Henriette Pfalzheim",
        "Marie Bertrand",
        "Guillermo Fernández",
        "Georg Pipps",
        "Isabel de Castro",
        "Bernardo Batista",
        "Lúcia Carvalho",
        "Horst Kloss",
        "Sergio Gutiérrez",
        "Paula Wilson",
        "Maurizio Moroni",
        "Janete Limeira",
        "Michael Holz",
        "Alejandra Camino",
        "Jonas Bergulfsen",
        "Jose Pavarotti",
        "Hari Kumar",
        "Jytte Petersen",
        "Dominique Perrier",
        "Art Braunschweiger",
        "Pascale Cartrain",
        "Liz Nixon",
        "Liu Wong",
        "Karin Josephs",
        "Miguel Angel Paolino",
        "Anabela Domingues",
        "Helvetius Nagy",
        "Palle Ibsen",
        "Mary Saveley",
        "Paul Henriot",
        "Rita Müller",
        "Pirkko Koskitalo",
        "Paula Parente",
        "Karl Jablonski",
        "Matti Karttunen",
        "Zbyszek Piestrzeniewicz"
    ];
    let customeraddress = [
        "507 - 20th Ave. E.\r\nApt. 2A",
        "908 W. Capital Way",
        "722 Moss Bay Blvd.",
        "4110 Old Redmond Rd.",
        "14 Garrett Hill",
        "Coventry House\r\nMiner Rd.",
        "Edgeham Hollow\r\nWinchester Way",
        "4726 - 11th Ave. N.E.",
        "7 Houndstooth Rd.",
        "59 rue de l'Abbaye",
        "Luisenstr. 48",
        "908 W. Capital Way",
        "722 Moss Bay Blvd.",
        "4110 Old Redmond Rd.",
        "14 Garrett Hill",
        "Coventry House\r\nMiner Rd.",
        "Edgeham Hollow\r\nWinchester Way",
        "7 Houndstooth Rd.",
        "2817 Milton Dr.",
        "Kirchgasse 6",
        "Sierras de Granada 9993",
        "Mehrheimerstr. 369",
        "Rua da Panificadora, 12",
        "2817 Milton Dr.",
        "Mehrheimerstr. 369"
    ];
    let quantityperunit = [
        "10 boxes x 20 bags",
        "24 - 12 oz bottles",
        "12 - 550 ml bottles",
        "48 - 6 oz jars",
        "36 boxes",
        "12 - 8 oz jars",
        "12 - 1 lb pkgs.",
        "12 - 12 oz jars",
        "18 - 500 g pkgs.",
        "12 - 200 ml jars",
        "1 kg pkg.",
        "10 - 500 g pkgs.",
        "2 kg box",
        "40 - 100 g pkgs.",
        "24 - 250 ml bottles",
        "32 - 500 g boxes",
        "20 - 1 kg tins",
        "16 kg pkg.",
        "10 boxes x 12 pieces",
        "30 gift boxes",
        "24 pkgs. x 4 pieces",
        "24 - 500 g pkgs.",
        "12 - 250 g pkgs.",
        "12 - 355 ml cans",
        "20 - 450 g glasses",
        "100 - 250 g bags"
    ];
    let orderID = 10248;
    let k = 1;
    for (let i = 0; i < 1000; i++) {
        k = k > 9 ? 1 : k;
        lazyLoadData.push({
            OrderID: orderID + i,
            CustomerID: customerid[Math.floor(Math.random() * customerid.length)],
            CustomerName: customername[Math.floor(Math.random() * customername.length)],
            CustomerAddress: customeraddress[Math.floor(Math.random() * customeraddress.length)],
            ProductName: product[Math.floor(Math.random() * product.length)],
            ProductID: i,
            Quantity: quantityperunit[Math.floor(Math.random() * quantityperunit.length)],
            Id: k
        });
        k++;
    }
    return lazyLoadData;
}
export let data: Object[] = createLazyLoadData();

function createLazyLoadData() {
  let lazyLoadData: Object[] = [];
  let customerid: string[] = [
    "VINET",
    "TOMSP",
    "HANAR",
    "VICTE",
    "SUPRD",
    "HANAR",
    "CHOPS",
    "RICSU",
    "WELLI",
    "HILAA",
    "ERNSH",
    "CENTC",
    "OTTIK",
    "QUEDE",
    "RATTC",
    "ERNSH",
    "FOLKO",
    "BLONP",
    "WARTH",
    "FRANK",
    "GROSR",
    "WHITC",
    "WARTH",
    "SPLIR",
    "RATTC",
    "QUICK",
    "VINET",
    "MAGAA",
    "TORTU",
    "MORGK",
    "BERGS",
    "LEHMS",
    "BERGS",
    "ROMEY",
    "ROMEY",
    "LILAS",
    "LEHMS",
    "QUICK",
    "QUICK",
    "RICAR",
    "REGGC",
    "BSBEV",
    "COMMI",
    "QUEDE",
    "TRADH",
    "TORTU",
    "RATTC",
    "VINET",
    "LILAS",
    "BLONP",
    "HUNGO",
    "RICAR",
    "MAGAA",
    "WANDK",
    "SUPRD",
    "GODOS",
    "TORTU",
    "OLDWO",
    "ROMEY",
    "LONEP",
    "ANATR",
    "HUNGO",
    "THEBI",
    "DUMON",
    "WANDK",
    "QUICK",
    "RATTC",
    "ISLAT",
    "RATTC",
    "LONEP",
    "ISLAT",
    "TORTU",
    "WARTH",
    "ISLAT",
    "PERIC",
    "KOENE",
    "SAVEA",
    "KOENE",
    "BOLID",
    "FOLKO",
    "FURIB",
    "SPLIR",
    "LILAS",
    "BONAP",
    "MEREP",
    "WARTH",
    "VICTE",
    "HUNGO",
    "PRINI",
    "FRANK",
    "OLDWO",
    "MEREP",
    "BONAP",
    "SIMOB",
    "FRANK",
    "LEHMS",
    "WHITC",
    "QUICK",
    "RATTC",
    "FAMIA"
  ];

  let product: string[] = [
    "Chai",
    "Chang",
    "Aniseed Syrup",
    "Chef Anton's Cajun Seasoning",
    "Chef Anton's Gumbo Mix",
    "Grandma's Boysenberry Spread",
    "Uncle Bob's Organic Dried Pears",
    "Northwoods Cranberry Sauce",
    "Mishi Kobe Niku",
    "Ikura",
    "Queso Cabrales",
    "Queso Manchego La Pastora",
    "Konbu",
    "Tofu",
    "Genen Shouyu",
    "Pavlova",
    "Alice Mutton",
    "Carnarvon Tigers",
    "Teatime Chocolate Biscuits",
    "Sir Rodney's Marmalade",
    "Sir Rodney's Scones",
    "Gustaf's Knäckebröd",
    "Tunnbröd",
    "Guaraná Fantástica",
    "NuNuCa Nuß-Nougat-Creme",
    "Gumbär Gummibärchen",
    "Schoggi Schokolade",
    "Rössle Sauerkraut",
    "Thüringer Rostbratwurst",
    "Nord-Ost Matjeshering",
    "Gorgonzola Telino",
    "Mascarpone Fabioli",
    "Geitost",
    "Sasquatch Ale",
    "Steeleye Stout",
    "Inlagd Sill",
    "Gravad lax",
    "Côte de Blaye",
    "Chartreuse verte",
    "Boston Crab Meat",
    "Jack's New England Clam Chowder",
    "Singaporean Hokkien Fried Mee",
    "Ipoh Coffee",
    "Gula Malacca",
    "Rogede sild",
    "Spegesild",
    "Zaanse koeken",
    "Chocolade",
    "Maxilaku",
    "Valkoinen suklaa",
    "Manjimup Dried Apples",
    "Filo Mix",
    "Perth Pasties",
    "Tourtière",
    "Pâté chinois",
    "Gnocchi di nonna Alice",
    "Ravioli Angelo",
    "Escargots de Bourgogne",
    "Raclette Courdavault",
    "Camembert Pierrot",
    "Sirop d'érable",
    "Tarte au sucre",
    "Vegie-spread",
    "Wimmers gute Semmelknödel",
    "Louisiana Fiery Hot Pepper Sauce",
    "Louisiana Hot Spiced Okra",
    "Laughing Lumberjack Lager",
    "Scottish Longbreads",
    "Gudbrandsdalsost",
    "Outback Lager",
    "Flotemysost",
    "Mozzarella di Giovanni",
    "Röd Kaviar",
    "Longlife Tofu",
    "Rhönbräu Klosterbier",
    "Lakkalikööri",
    "Original Frankfurter grüne Soße"
  ];

  let customername: string[] = [
    "Maria",
    "Ana Trujillo",
    "Antonio Moreno",
    "Thomas Hardy",
    "Christina Berglund",
    "Hanna Moos",
    "Frédérique Citeaux",
    "Martín Sommer",
    "Laurence Lebihan",
    "Elizabeth Lincoln",
    "Victoria Ashworth",
    "Patricio Simpson",
    "Francisco Chang",
    "Yang Wang",
    "Pedro Afonso",
    "Elizabeth Brown",
    "Sven Ottlieb",
    "Janine Labrune",
    "Ann Devon",
    "Roland Mendel",
    "Aria Cruz",
    "Diego Roel",
    "Martine Rancé",
    "Maria Larsson",
    "Peter Franken",
    "Carine Schmitt",
    "Paolo Accorti",
    "Lino Rodriguez",
    "Eduardo Saavedra",
    "José Pedro Freyre",
    "André Fonseca",
    "Howard Snyder",
    "Manuel Pereira",
    "Mario Pontes",
    "Carlos Hernández",
    "Yoshi Latimer",
    "Patricia McKenna",
    "Helen Bennett",
    "Philip Cramer",
    "Daniel Tonini",
    "Annette Roulet",
    "Yoshi Tannamuri",
    "John Steel",
    "Renate Messner",
    "Jaime Yorres",
    "Carlos González",
    "Felipe Izquierdo",
    "Fran Wilson",
    "Giovanni Rovelli",
    "Catherine Dewey",
    "Jean Fresnière",
    "Alexander Feuer",
    "Simon Crowther",
    "Yvonne Moncada",
    "Rene Phillips",
    "Henriette Pfalzheim",
    "Marie Bertrand",
    "Guillermo Fernández",
    "Georg Pipps",
    "Isabel de Castro",
    "Bernardo Batista",
    "Lúcia Carvalho",
    "Horst Kloss",
    "Sergio Gutiérrez",
    "Paula Wilson",
    "Maurizio Moroni",
    "Janete Limeira",
    "Michael Holz",
    "Alejandra Camino",
    "Jonas Bergulfsen",
    "Jose Pavarotti",
    "Hari Kumar",
    "Jytte Petersen",
    "Dominique Perrier",
    "Art Braunschweiger",
    "Pascale Cartrain",
    "Liz Nixon",
    "Liu Wong",
    "Karin Josephs",
    "Miguel Angel Paolino",
    "Anabela Domingues",
    "Helvetius Nagy",
    "Palle Ibsen",
    "Mary Saveley",
    "Paul Henriot",
    "Rita Müller",
    "Pirkko Koskitalo",
    "Paula Parente",
    "Karl Jablonski",
    "Matti Karttunen",
    "Zbyszek Piestrzeniewicz"
  ];

  let customeraddress: string[] = [
    "507 - 20th Ave. E.\r\nApt. 2A",
    "908 W. Capital Way",
    "722 Moss Bay Blvd.",
    "4110 Old Redmond Rd.",
    "14 Garrett Hill",
    "Coventry House\r\nMiner Rd.",
    "Edgeham Hollow\r\nWinchester Way",
    "4726 - 11th Ave. N.E.",
    "7 Houndstooth Rd.",
    "59 rue de l'Abbaye",
    "Luisenstr. 48",
    "908 W. Capital Way",
    "722 Moss Bay Blvd.",
    "4110 Old Redmond Rd.",
    "14 Garrett Hill",
    "Coventry House\r\nMiner Rd.",
    "Edgeham Hollow\r\nWinchester Way",
    "7 Houndstooth Rd.",
    "2817 Milton Dr.",
    "Kirchgasse 6",
    "Sierras de Granada 9993",
    "Mehrheimerstr. 369",
    "Rua da Panificadora, 12",
    "2817 Milton Dr.",
    "Mehrheimerstr. 369"
  ];

  let quantityperunit: string[] = [
    "10 boxes x 20 bags",
    "24 - 12 oz bottles",
    "12 - 550 ml bottles",
    "48 - 6 oz jars",
    "36 boxes",
    "12 - 8 oz jars",
    "12 - 1 lb pkgs.",
    "12 - 12 oz jars",
    "18 - 500 g pkgs.",
    "12 - 200 ml jars",
    "1 kg pkg.",
    "10 - 500 g pkgs.",
    "2 kg box",
    "40 - 100 g pkgs.",
    "24 - 250 ml bottles",
    "32 - 500 g boxes",
    "20 - 1 kg tins",
    "16 kg pkg.",
    "10 boxes x 12 pieces",
    "30 gift boxes",
    "24 pkgs. x 4 pieces",
    "24 - 500 g pkgs.",
    "12 - 250 g pkgs.",
    "12 - 355 ml cans",
    "20 - 450 g glasses",
    "100 - 250 g bags"
  ];

  let orderID: number = 10248;
  let k: number = 1;
  for (let i: number = 0; i < 1000; i++) {
    k = k > 9 ? 1 : k;
    lazyLoadData.push({
      OrderID: orderID + i,
      CustomerID: customerid[Math.floor(Math.random() * customerid.length)],
      CustomerName:
        customername[Math.floor(Math.random() * customername.length)],
      CustomerAddress:
        customeraddress[Math.floor(Math.random() * customeraddress.length)],
      ProductName: product[Math.floor(Math.random() * product.length)],
      ProductID: i,
      Quantity:
        quantityperunit[Math.floor(Math.random() * quantityperunit.length)],
      Id: k
    });
    k++;
  }
  return lazyLoadData;
}

Limitations

The following features are not supported in the immutable mode:

  • Frozen rows and columns
  • Grouping
  • Row Template
  • Detail Template
  • Hierarchy Grid
  • Scrolling
  • Virtual scroll
  • Infinite scroll
  • Column reorder
  • Rows, column spanning
  • PDF export, Excel export, Print
  • Column Resize
  • Drag and drop
  • Column template
  • Column chooser
  • Clipboard
  • AutoFit
  • Filtering