Syncfusion AI Assistant

How can I help you?

Data binding in React Grid Component

27 Mar 202624 minutes to read

Data binding is a fundamental technique that empowers the Grid component to integrate data into its interface, enabling the creation of dynamic and interactive grid views. This feature is particularly valuable when working with large datasets or when data needs to be fetched remotely.

The Syncfusion® React Grid utilizes the DataManager, which supports both local binding with JavaScript object arrays and remote binding with RESTful JSON data services. The key property, dataSource, can be assigned to a DataManager instance or a collection of JavaScript object arrays.

It supports two kinds of data binding methods:

  • Local data
  • Remote data

To learn about binding local or remote data to the React Grid, refer to this video:

Loading indicator

The Syncfusion® React Grid provides a loading animation feature, which makes it easy to identify when data is being loaded or refreshed. This feature provides a clear understanding of the grid’s current state and actions, such as sorting, filtering, grouping, and more.

To achieve this, the loadingIndicator.indicatorType property of the grid can be utilized, which supports two types of indicators:

  • Spinner (default)
  • Shimmer

The following example demonstrates setting the loadingIndicator.indicatorType property based on changing the dropdown value using the change event of the DropDownList component. The refreshColumns method is used to apply the changes and display the updated loading indicator type.

import { DataManager, UrlAdaptor } from '@syncfusion/ej2-data';
import { ColumnDirective, ColumnsDirective, GridComponent, Inject, Page, Sort, Filter, PageSettingsModel } from '@syncfusion/ej2-react-grids';
import { DropDownListComponent } from '@syncfusion/ej2-react-dropdowns';
import * as React from 'react';

function App() {
  let grid;
  let dropDown;
  const data = new DataManager({
    url: 'https://services.syncfusion.com/react/production/api/UrlDataSource',
    adaptor: new UrlAdaptor
  });
  const pageOptions = { pageSize: 5, pageCount: 5 };
  const loadingIndicator = { indicatorType: 'Spinner' };
  const ddlData = [
    { id: 'Spinner', value: 'Spinner' },
    { id: 'Shimmer', value: 'Shimmer' }
  ]
  const fields = { text: 'value', value: 'id' };
  const valueChange = () => {
    if (dropDown.value === 'Shimmer') {
      grid.loadingIndicator.indicatorType = 'Shimmer';
      grid.refreshColumns();
    } else {
      grid.loadingIndicator.indicatorType = 'Spinner';
      grid.refreshColumns();
    }
  }
  return (<div>
    <label style={{ padding: "10px 10px 26px 0" }}> Change the loading indicator type: </label>
    <DropDownListComponent ref={d => dropDown = d} index={0} width={120} dataSource={ddlData} fields={fields} change={valueChange}></DropDownListComponent>
    <GridComponent ref={g => grid = g} dataSource={data} allowPaging={true} pageSettings={pageOptions} height={315} allowFiltering={true} allowSorting={true} loadingIndicator={loadingIndicator}>
      <ColumnsDirective>
        <ColumnDirective field='EmployeeID' headerText='Employee ID' width='120' textAlign="Right" />
        <ColumnDirective field='Employees' headerText='Employees' width='150' />
        <ColumnDirective field='Designation' headerText='Designation' width='150' />
        <ColumnDirective field='CurrentSalary' headerText='Current Salary' width='150' />
      </ColumnsDirective>
      <Inject services={[Page, Sort, Filter]} />
    </GridComponent></div>)
};
export default App;
import { DataManager, UrlAdaptor } from '@syncfusion/ej2-data';
import { ColumnDirective, ColumnsDirective, GridComponent, Inject, Page, Sort, Filter, PageSettingsModel } from '@syncfusion/ej2-react-grids';
import { DropDownListComponent, ChangeEventArgs } from '@syncfusion/ej2-react-dropdowns';
import * as React from 'react';

function App() {
  let grid: GridComponent | null;
  let dropDown: DropDownListComponent | null;
  const data: DataManager = new DataManager({
    url: 'https://services.syncfusion.com/react/production/api/UrlDataSource',
    adaptor: new UrlAdaptor
  });
  const pageOptions: PageSettingsModel = { pageSize: 5, pageCount: 5 };
  const loadingIndicator = { indicatorType: 'Spinner' };
  const ddlData: Object[] = [
    { id: 'Spinner', value: 'Spinner' },
    { id: 'Shimmer', value: 'Shimmer' }
  ]
  const fields: object = { text: 'value', value: 'id' };
  const valueChange = (args: ChangeEventArgs) => {
    if ((dropDown as DropDownListComponent).value === 'Shimmer') {
      (grid as GridComponent).loadingIndicator.indicatorType = 'Shimmer';
      (grid as GridComponent).refreshColumns();
    } else {
      (grid as GridComponent).loadingIndicator.indicatorType = 'Spinner';
      (grid as GridComponent).refreshColumns();
    }
  }
  return (<div>
    <label style={{ padding: "10px 10px 26px 0" }}> Change the loading indicator type: </label>
    <DropDownListComponent ref={d => dropDown = d} index={0} width={120} dataSource={ddlData} fields={fields} change={valueChange}></DropDownListComponent>
    <GridComponent ref={g => grid = g} dataSource={data} allowPaging={true} pageSettings={pageOptions} height={315} allowFiltering={true} allowSorting={true} loadingIndicator={loadingIndicator}>
      <ColumnsDirective>
        <ColumnDirective field='EmployeeID' headerText='Employee ID' width='120' textAlign="Right" />
        <ColumnDirective field='Employees' headerText='Employees' width='150' />
        <ColumnDirective field='Designation' headerText='Designation' width='150' />
        <ColumnDirective field='CurrentSalary' headerText='Current Salary' width='150' />
      </ColumnsDirective>
      <Inject services={[Page, Sort, Filter]} />
    </GridComponent></div>)
};
export default App;

Refresh the datasource using property

Refreshing the data source in a Syncfusion® React Grid involves updating the data that the grid displays dynamically. This operation reflects changes in the underlying data without reloading the entire page or component.

To achieve this, use the datasource property in conjunction with the setProperties method. This ensures the grid reflects changes in the dataSource without requiring a complete page or component reload.

For example, when adding or deleting data source records, follow these steps:

Step 1: Add/delete the datasource record by using the following code.

grid.dataSource.unshift(data); // Add a new record.
grid.dataSource.splice(selectedRow, 1); // Delete a record.

Step 2: Refresh the datasource after changes by invoking the setProperties method.

(grid as GridComponent).setProperties({ dataSource:  (grid as GridComponent).dataSource as object[] });

The following example demonstrates adding a new record to the data source through an external button:

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

function App() {
    let grid;
    let newRecords = [];
    // Generate a random OrderId
    const generateOrderId = () => {
        return Math.floor(10000 + Math.random() * 90000);
    }
    // Generate a random CustomerId
    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;
    }
    // Generate a random ShipCity
    const generateShipCity = () => {
        const cities = ['London', 'Paris', 'New York', 'Tokyo', 'Berlin'];
        return cities[Math.floor(Math.random() * cities.length)];
    }
    // Generate a random Freight value
    const generateFreight = () => {
        return Math.random() * 100;
    }
    // Generate a random ShipName
    const generateShipName = () => {
        const names = ['Que Delícia', 'Bueno Foods', 'Island Trading', 'Laughing Bacchus Winecellars'];
        return names[Math.floor(Math.random() * names.length)];
    }
    const changeDatasource = () => {
        for (let i = 0; i < 5; i++) {
            newRecords = {
                OrderID: generateOrderId(),
                CustomerID: generateCustomerId(),
                ShipCity: generateShipCity(),
                Freight: generateFreight(),
                ShipName: generateShipName()
            };

            (grid.dataSource).unshift(newRecords);
            grid.setProperties({ dataSource: grid.dataSource });
        }
    }
    return <div>
        <ButtonComponent onClick={changeDatasource}>Change Datasource</ButtonComponent>
        <GridComponent dataSource={data} height={280} ref={g => grid = g}>
            <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='Freight' headerText='Freight' width='150' format='C2' />
                <ColumnDirective field='ShipName' headerText='Ship Name' width='150' />
            </ColumnsDirective>
        </GridComponent>
    </div>
};
export default App;
import { ButtonComponent } from '@syncfusion/ej2-react-buttons';
import { ColumnDirective, ColumnsDirective, Grid, GridComponent } from '@syncfusion/ej2-react-grids';
import * as React from 'react';
import { data } from './datasource';

function App() {
    let grid: GridComponent | null;
    let newRecords: Object = [];
    // Generate a random OrderId
    const generateOrderId = () => {
        return Math.floor(10000 + Math.random() * 90000);
    }
    // Generate a random CustomerId
    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;
    }
    // Generate a random ShipCity
    const generateShipCity = () => {
        const cities = ['London', 'Paris', 'New York', 'Tokyo', 'Berlin'];
        return cities[Math.floor(Math.random() * cities.length)];
    }
    // Generate a random Freight value
    const generateFreight = () => {
        return Math.random() * 100;
    }
    // Generate a random ShipName
    const generateShipName = () => {
        const names = ['Que Delícia', 'Bueno Foods', 'Island Trading', 'Laughing Bacchus Winecellars'];
        return names[Math.floor(Math.random() * names.length)];
    }
    const changeDatasource = () => {
        for (let i = 0; i < 5; i++) {
            newRecords = {
                OrderID: generateOrderId(),
                CustomerID: generateCustomerId(),
                ShipCity: generateShipCity(),
                Freight: generateFreight(),
                ShipName: generateShipName()
            };

            ((grid as GridComponent).dataSource as object[]).unshift(newRecords);
            (grid as GridComponent).setProperties({ dataSource: (grid as GridComponent).dataSource as object[] });
        }
    }
    return <div>
        <ButtonComponent onClick={changeDatasource}>Change Datasource</ButtonComponent>
        <GridComponent dataSource={data} height={280} ref={g => grid = g}>
            <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='Freight' headerText='Freight' width='150' format='C2' />
                <ColumnDirective field='ShipName' headerText='Ship Name' width='150' />
            </ColumnsDirective>
        </GridComponent>
    </div>
};
export default App;
export let data = [
    {
        OrderID: 10248, CustomerID: 'VINET', Role: 'Admin', EmployeeID: 5, OrderDate: new Date(8364186e5),
        ShipName: 'Vins et alcools Chevalier', ShipCity: 'Reims', ShipAddress: '59 rue de l Abbaye',
        ShipRegion: 'CJ', Mask: '1111', ShipPostalCode: '51100', ShipCountry: 'France', Freight: 32.38, Verified: !0
    },
    {
        OrderID: 10249, CustomerID: 'TOMSP', Role: 'Employee', EmployeeID: 6, OrderDate: new Date(836505e6),
        ShipName: 'Toms Spezialitäten', ShipCity: 'Münster', ShipAddress: 'Luisenstr. 48',
        ShipRegion: 'CJ', Mask: '2222', ShipPostalCode: '44087', ShipCountry: 'Germany', Freight: 11.61, Verified: !1
    },
    {
        OrderID: 10250, CustomerID: 'HANAR', Role: 'Admin', EmployeeID: 4, OrderDate: new Date(8367642e5),
        ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67',
        ShipRegion: 'RJ', Mask: '3333', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 65.83, Verified: !0
    },
    {
        OrderID: 10251, CustomerID: 'VICTE', Role: 'Manager', EmployeeID: 3, OrderDate: new Date(8367642e5),
        ShipName: 'Victuailles en stock', ShipCity: 'Lyon', ShipAddress: '2, rue du Commerce',
        ShipRegion: 'CJ', Mask: '4444', ShipPostalCode: '69004', ShipCountry: 'France', Freight: 41.34, Verified: !0
    },
    {
        OrderID: 10252, CustomerID: 'SUPRD', Role: 'Manager', EmployeeID: 4, OrderDate: new Date(8368506e5),
        ShipName: 'Suprêmes délices', ShipCity: 'Charleroi', ShipAddress: 'Boulevard Tirou, 255',
        ShipRegion: 'CJ', Mask: '5555', ShipPostalCode: 'B-6000', ShipCountry: 'Belgium', Freight: 51.3, Verified: !0
    },
    {
        OrderID: 10253, CustomerID: 'HANAR', Role: 'Admin', EmployeeID: 3, OrderDate: new Date(836937e6),
        ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67',
        ShipRegion: 'RJ', Mask: '6666', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 58.17, Verified: !0
    },
    {
        OrderID: 10254, CustomerID: 'CHOPS', Role: 'Employee', EmployeeID: 5, OrderDate: new Date(8370234e5),
        ShipName: 'Chop-suey Chinese', ShipCity: 'Bern', ShipAddress: 'Hauptstr. 31',
        ShipRegion: 'CJ', Mask: '7777', ShipPostalCode: '3012', ShipCountry: 'Switzerland', Freight: 22.98, Verified: !1
    },
    {
        OrderID: 10255, CustomerID: 'RICSU', Role: 'Admin', EmployeeID: 9, OrderDate: new Date(8371098e5),
        ShipName: 'Richter Supermarkt', ShipCity: 'Genève', ShipAddress: 'Starenweg 5',
        ShipRegion: 'CJ', Mask: '8888', ShipPostalCode: '1204', ShipCountry: 'Switzerland', Freight: 148.33, Verified: !0
    },
    {
        OrderID: 10256, CustomerID: 'WELLI', Role: 'Employee', EmployeeID: 3, OrderDate: new Date(837369e6),
        ShipName: 'Wellington Importadora', ShipCity: 'Resende', ShipAddress: 'Rua do Mercado, 12',
        ShipRegion: 'SP', Mask: '9999', ShipPostalCode: '08737-363', ShipCountry: 'Brazil', Freight: 13.97, Verified: !1
    },
    {
        OrderID: 10257, CustomerID: 'HILAA', Role: 'Admin', 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', Mask: '1234', ShipPostalCode: '5022', ShipCountry: 'Venezuela', Freight: 81.91, Verified: !0
    },
    {
        OrderID: 10258, CustomerID: 'ERNSH', Role: 'Manager', EmployeeID: 1, OrderDate: new Date(8375418e5),
        ShipName: 'Ernst Handel', ShipCity: 'Graz', ShipAddress: 'Kirchgasse 6',
        ShipRegion: 'CJ', Mask: '2345', ShipPostalCode: '8010', ShipCountry: 'Austria', Freight: 140.51, Verified: !0
    },
    {
        OrderID: 10259, CustomerID: 'CENTC', Role: 'Admin', EmployeeID: 4, OrderDate: new Date(8376282e5),
        ShipName: 'Centro comercial Moctezuma', ShipCity: 'México D.F.', ShipAddress: 'Sierras de Granada 9993',
        ShipRegion: 'CJ', Mask: '3456', ShipPostalCode: '05022', ShipCountry: 'Mexico', Freight: 3.25, Verified: !1
    },
    {
        OrderID: 10260, CustomerID: 'OTTIK', Role: 'Admin', EmployeeID: 4, OrderDate: new Date(8377146e5),
        ShipName: 'Ottilies Käseladen', ShipCity: 'Köln', ShipAddress: 'Mehrheimerstr. 369',
        ShipRegion: 'CJ', Mask: '4567', ShipPostalCode: '50739', ShipCountry: 'Germany', Freight: 55.09, Verified: !0
    },
    {
        OrderID: 10261, CustomerID: 'QUEDE', Role: 'Manager', EmployeeID: 4, OrderDate: new Date(8377146e5),
        ShipName: 'Que Delícia', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua da Panificadora, 12',
        ShipRegion: 'RJ', Mask: '5678', ShipPostalCode: '02389-673', ShipCountry: 'Brazil', Freight: 3.05, Verified: !1
    },
    {
        OrderID: 10262, CustomerID: 'RATTC', Role: 'Employee', EmployeeID: 8, OrderDate: new Date(8379738e5),
        ShipName: 'Rattlesnake Canyon Grocery', ShipCity: 'Albuquerque', ShipAddress: '2817 Milton Dr.',
        ShipRegion: 'NM', Mask: '6789', ShipPostalCode: '87110', ShipCountry: 'USA', Freight: 48.29, Verified: !0
    }
];
export let data: Object[] = [
    {
        OrderID: 10248, CustomerID: 'VINET', Role: 'Admin', EmployeeID: 5, OrderDate: new Date(8364186e5),
        ShipName: 'Vins et alcools Chevalier', ShipCity: 'Reims', ShipAddress: '59 rue de l Abbaye',
        ShipRegion: 'CJ', Mask: '1111', ShipPostalCode: '51100', ShipCountry: 'France', Freight: 32.38, Verified: !0
    },
    {
        OrderID: 10249, CustomerID: 'TOMSP', Role: 'Employee', EmployeeID: 6, OrderDate: new Date(836505e6),
        ShipName: 'Toms Spezialitäten', ShipCity: 'Münster', ShipAddress: 'Luisenstr. 48',
        ShipRegion: 'CJ', Mask: '2222', ShipPostalCode: '44087', ShipCountry: 'Germany', Freight: 11.61, Verified: !1
    },
    {
        OrderID: 10250, CustomerID: 'HANAR', Role: 'Admin', EmployeeID: 4, OrderDate: new Date(8367642e5),
        ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67',
        ShipRegion: 'RJ', Mask: '3333', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 65.83, Verified: !0
    },
    {
        OrderID: 10251, CustomerID: 'VICTE', Role: 'Manager', EmployeeID: 3, OrderDate: new Date(8367642e5),
        ShipName: 'Victuailles en stock', ShipCity: 'Lyon', ShipAddress: '2, rue du Commerce',
        ShipRegion: 'CJ', Mask: '4444', ShipPostalCode: '69004', ShipCountry: 'France', Freight: 41.34, Verified: !0
    },
    {
        OrderID: 10252, CustomerID: 'SUPRD', Role: 'Manager', EmployeeID: 4, OrderDate: new Date(8368506e5),
        ShipName: 'Suprêmes délices', ShipCity: 'Charleroi', ShipAddress: 'Boulevard Tirou, 255',
        ShipRegion: 'CJ', Mask: '5555', ShipPostalCode: 'B-6000', ShipCountry: 'Belgium', Freight: 51.3, Verified: !0
    },
    {
        OrderID: 10253, CustomerID: 'HANAR', Role: 'Admin', EmployeeID: 3, OrderDate: new Date(836937e6),
        ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67',
        ShipRegion: 'RJ', Mask: '6666', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 58.17, Verified: !0
    },
    {
        OrderID: 10254, CustomerID: 'CHOPS', Role: 'Employee', EmployeeID: 5, OrderDate: new Date(8370234e5),
        ShipName: 'Chop-suey Chinese', ShipCity: 'Bern', ShipAddress: 'Hauptstr. 31',
        ShipRegion: 'CJ',  Mask: '7777', ShipPostalCode: '3012', ShipCountry: 'Switzerland', Freight: 22.98, Verified: !1
    },
    {
        OrderID: 10255, CustomerID: 'RICSU', Role: 'Admin', EmployeeID: 9, OrderDate: new Date(8371098e5),
        ShipName: 'Richter Supermarkt', ShipCity: 'Genève', ShipAddress: 'Starenweg 5',
        ShipRegion: 'CJ', Mask: '8888', ShipPostalCode: '1204', ShipCountry: 'Switzerland', Freight: 148.33, Verified: !0
    },
    {
        OrderID: 10256, CustomerID: 'WELLI', Role: 'Employee', EmployeeID: 3, OrderDate: new Date(837369e6),
        ShipName: 'Wellington Importadora', ShipCity: 'Resende', ShipAddress: 'Rua do Mercado, 12',
        ShipRegion: 'SP', Mask: '9999', ShipPostalCode: '08737-363', ShipCountry: 'Brazil', Freight: 13.97, Verified: !1
    },
    {
        OrderID: 10257, CustomerID: 'HILAA', Role: 'Admin', 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', Mask: '1234', ShipPostalCode: '5022', ShipCountry: 'Venezuela', Freight: 81.91, Verified: !0
    },
    {
        OrderID: 10258, CustomerID: 'ERNSH', Role: 'Manager', EmployeeID: 1, OrderDate: new Date(8375418e5),
        ShipName: 'Ernst Handel', ShipCity: 'Graz', ShipAddress: 'Kirchgasse 6',
        ShipRegion: 'CJ', Mask: '2345', ShipPostalCode: '8010', ShipCountry: 'Austria', Freight: 140.51, Verified: !0
    },
    {
        OrderID: 10259, CustomerID: 'CENTC', Role: 'Admin', EmployeeID: 4, OrderDate: new Date(8376282e5),
        ShipName: 'Centro comercial Moctezuma', ShipCity: 'México D.F.', ShipAddress: 'Sierras de Granada 9993',
        ShipRegion: 'CJ', Mask: '3456', ShipPostalCode: '05022', ShipCountry: 'Mexico', Freight: 3.25, Verified: !1
    },
    {
        OrderID: 10260, CustomerID: 'OTTIK', Role: 'Admin', EmployeeID: 4, OrderDate: new Date(8377146e5),
        ShipName: 'Ottilies Käseladen', ShipCity: 'Köln', ShipAddress: 'Mehrheimerstr. 369',
        ShipRegion: 'CJ', Mask: '4567', ShipPostalCode: '50739', ShipCountry: 'Germany', Freight: 55.09, Verified: !0
    },
    {
        OrderID: 10261, CustomerID: 'QUEDE', Role: 'Manager', EmployeeID: 4, OrderDate: new Date(8377146e5),
        ShipName: 'Que Delícia', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua da Panificadora, 12',
        ShipRegion: 'RJ', Mask: '5678', ShipPostalCode: '02389-673', ShipCountry: 'Brazil', Freight: 3.05, Verified: !1
    },
    {
        OrderID: 10262, CustomerID: 'RATTC', Role: 'Employee', EmployeeID: 8, OrderDate: new Date(8379738e5),
        ShipName: 'Rattlesnake Canyon Grocery', ShipCity: 'Albuquerque', ShipAddress: '2817 Milton Dr.',
        ShipRegion: 'NM', Mask: '6789', ShipPostalCode: '87110', ShipCountry: 'USA', Freight: 48.29, Verified: !0
    }];

Dynamically change the datasource or columns or both

The Syncfusion® React Grid component supports dynamic modification of the data source, columns, or both. This feature refreshes the grid’s content and structure without requiring a complete page reload.

To achieve dynamic changes, the changeDataSource method allows updating the grid’s data source dynamically. This method enables updating the data source, columns, or both, based on application requirements. However, it is important to note that during the changing process for the data source and columns, the grid’s existing actions such as sorting, filtering, grouping, aggregation, and searching will be reset. The changeDataSource method has two optional arguments: the first argument represents the data source, and the second argument represents the columns. The various uses of the changeDataSource method are explained in the following topic.

1. Change both data source and columns:

To modify both the existing columns and the data source, pass both arguments to the changeDataSource method. The following example demonstrates changing both the data source and columns.

Assign a JavaScript object array to the dataSource property to bind local data to the grid. The code below provides an example of creating a data source for the grid.

export let data: Object[] = [
{
    OrderID: 10248, CustomerID: 'VINET', Freight: 32.38,
    ShipCity: 'Reims'
},
{
    OrderID: 10249, CustomerID: 'TOMSP', Freight: 11.61,
    ShipCity: 'Münster'
},
{
    OrderID: 10250, CustomerID: 'HANAR', Freight: 61.34,
    ShipCity: 'Rio de Janeiro'
}];

The following code demonstrates creating the columns for the grid, which are based on the provided grid data source.

const newColumn: ColumnModel[] = [
    { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 125 },
    { field: 'CustomerID', headerText: 'Customer ID', width: 125 },
];

The following code demonstrates updating the data source and columns defined above using the changeDataSource method.

    gridInstance.changeDataSource(data, newColumn);

2. Modify only the existing columns:

To modify existing columns in a grid, add or remove columns or replace the entire set of columns using the changeDataSource method. To use this method, set the first parameter to “null” and provide the new columns as the second parameter. Note that if a column field is not specified in the dataSource, its corresponding column values will be empty. The following example illustrates modifying existing columns.

The following code demonstrates adding new columns to existing grid columns “newColumn” by using the changeDataSource method.

const newColumn: ColumnModel[] = [
    { field: 'Freight', headerText: 'Freight', textAlign: 'Right', width: 125 },
    { field: 'ShipCity', headerText: 'ShipCity', width: 125 },
];
let column: any = newColumn.push(...newColumn);
gridInstance.changeDataSource(null, column);

3. Modify only the data source:

The changeDataSource method provides option to change the entire data source in the grid by passing the new data source as the first argument. Provide the data source as the first argument; the optional second argument can specify new columns for the grid. If columns are not specified, the grid auto-generates columns based on the data source. The following example demonstrates modifying the data source.

Assign a JavaScript object array to the dataSource property to bind local data to the grid. The code below provides an example of creating a new data source for the grid.

export let employeeData: Object[] = [
{
    FirstName: 'Nancy', City: 'Seattle', Region: 'WA',
    Country: 'USA'
},
{
    FirstName: 'Andrew', City: 'London', Region: null,
    Country: 'UK',
},
{
    FirstName: 'Janet', City: 'Kirkland', Region: 'WA',
    Country: 'USA'
}];

The following code demonstrates the use of changeDataSource method to bind the new “employeeData” to the grid.

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

function App() {
    let grid;
    let count = 0;
    const pageSettings = { pageSize: 5, pageCount: 3 };
    const newColumn = [
        { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 125 },
        { field: 'CustomerID', headerText: 'Customer Name', width: 125 },
        { field: 'OrderDate', headerText: 'Order Date', width: 130, format: 'yMd', textAlign: 'Right' },
        { field: 'Freight', headerText: 'Freight', width: 120, textAlign: 'Right' },
    ];
    const onClick = () => {
        count = count + 100;
        grid.changeDataSource(data.slice(0, count + 100), newColumn);
    }
    return <div>
        <ButtonComponent onClick={onClick}>Click Button</ButtonComponent>
        <GridComponent dataSource={data} height={280} ref={g => grid = g} allowPaging={true} pageSettings={pageSettings}>
            <ColumnsDirective>
                <ColumnDirective field='OrderID' headerText='Order ID' width='120' textAlign="Right" />
                <ColumnDirective field='CustomerID' headerText='Customer ID' width='150' />
                <ColumnDirective field='Freight' headerText='Freight' width='150' format='C2' />
            </ColumnsDirective>
            <Inject services={[Page]} />
        </GridComponent>
    </div>
};
export default App;
import { ButtonComponent } from '@syncfusion/ej2-react-buttons';
import { ColumnDirective, ColumnsDirective, GridComponent, PageSettingsModel, Inject, Page } from '@syncfusion/ej2-react-grids';
import * as React from 'react';
import { data } from './datasource';

function App() {
    let grid: GridComponent | null;
    let count: number = 0;
    const pageSettings: PageSettingsModel = { pageSize: 5, pageCount: 3 };
    const newColumn = [
        { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 125 },
        { field: 'CustomerID', headerText: 'Customer Name', width: 125 },
        { field: 'OrderDate', headerText: 'Order Date', width: 130, format: 'yMd' },
        { field: 'Freight', headerText: 'Freight', width: 120, format:'C2' },
    ];
    const onClick = () => {
        count = count + 100;
        (grid as GridComponent).changeDataSource(data.slice(0, count + 100), newColumn as Object[]);
    }
    return <div>
        <ButtonComponent onClick={onClick}>Click Button</ButtonComponent>
        <GridComponent dataSource={data} height={280} ref={g => grid = g} allowPaging={true} pageSettings={pageSettings}>
            <ColumnsDirective>
                <ColumnDirective field='OrderID' headerText='Order ID' width='120' textAlign="Right" />
                <ColumnDirective field='CustomerID' headerText='Customer ID' width='150' />
                <ColumnDirective field='Freight' headerText='Freight' width='150' format='C2' />
            </ColumnsDirective>
            <Inject services={[Page]} />
        </GridComponent>
    </div>
};
export default App;
export let data = [
    {
        OrderID: 10248, CustomerID: 'VINET', Role: 'Admin', EmployeeID: 5, OrderDate: new Date(8364186e5),
        ShipName: 'Vins et alcools Chevalier', ShipCity: 'Reims', ShipAddress: '59 rue de l Abbaye',
        ShipRegion: 'CJ', Mask: '1111', ShipPostalCode: '51100', ShipCountry: 'France', Freight: 32.38, Verified: !0
    },
    {
        OrderID: 10249, CustomerID: 'TOMSP', Role: 'Employee', EmployeeID: 6, OrderDate: new Date(836505e6),
        ShipName: 'Toms Spezialitäten', ShipCity: 'Münster', ShipAddress: 'Luisenstr. 48',
        ShipRegion: 'CJ', Mask: '2222', ShipPostalCode: '44087', ShipCountry: 'Germany', Freight: 11.61, Verified: !1
    },
    {
        OrderID: 10250, CustomerID: 'HANAR', Role: 'Admin', EmployeeID: 4, OrderDate: new Date(8367642e5),
        ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67',
        ShipRegion: 'RJ', Mask: '3333', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 65.83, Verified: !0
    },
    {
        OrderID: 10251, CustomerID: 'VICTE', Role: 'Manager', EmployeeID: 3, OrderDate: new Date(8367642e5),
        ShipName: 'Victuailles en stock', ShipCity: 'Lyon', ShipAddress: '2, rue du Commerce',
        ShipRegion: 'CJ', Mask: '4444', ShipPostalCode: '69004', ShipCountry: 'France', Freight: 41.34, Verified: !0
    },
    {
        OrderID: 10252, CustomerID: 'SUPRD', Role: 'Manager', EmployeeID: 4, OrderDate: new Date(8368506e5),
        ShipName: 'Suprêmes délices', ShipCity: 'Charleroi', ShipAddress: 'Boulevard Tirou, 255',
        ShipRegion: 'CJ', Mask: '5555', ShipPostalCode: 'B-6000', ShipCountry: 'Belgium', Freight: 51.3, Verified: !0
    },
    {
        OrderID: 10253, CustomerID: 'HANAR', Role: 'Admin', EmployeeID: 3, OrderDate: new Date(836937e6),
        ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67',
        ShipRegion: 'RJ', Mask: '6666', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 58.17, Verified: !0
    },
    {
        OrderID: 10254, CustomerID: 'CHOPS', Role: 'Employee', EmployeeID: 5, OrderDate: new Date(8370234e5),
        ShipName: 'Chop-suey Chinese', ShipCity: 'Bern', ShipAddress: 'Hauptstr. 31',
        ShipRegion: 'CJ', Mask: '7777', ShipPostalCode: '3012', ShipCountry: 'Switzerland', Freight: 22.98, Verified: !1
    },
    {
        OrderID: 10255, CustomerID: 'RICSU', Role: 'Admin', EmployeeID: 9, OrderDate: new Date(8371098e5),
        ShipName: 'Richter Supermarkt', ShipCity: 'Genève', ShipAddress: 'Starenweg 5',
        ShipRegion: 'CJ', Mask: '8888', ShipPostalCode: '1204', ShipCountry: 'Switzerland', Freight: 148.33, Verified: !0
    },
    {
        OrderID: 10256, CustomerID: 'WELLI', Role: 'Employee', EmployeeID: 3, OrderDate: new Date(837369e6),
        ShipName: 'Wellington Importadora', ShipCity: 'Resende', ShipAddress: 'Rua do Mercado, 12',
        ShipRegion: 'SP', Mask: '9999', ShipPostalCode: '08737-363', ShipCountry: 'Brazil', Freight: 13.97, Verified: !1
    },
    {
        OrderID: 10257, CustomerID: 'HILAA', Role: 'Admin', 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', Mask: '1234', ShipPostalCode: '5022', ShipCountry: 'Venezuela', Freight: 81.91, Verified: !0
    },
    {
        OrderID: 10258, CustomerID: 'ERNSH', Role: 'Manager', EmployeeID: 1, OrderDate: new Date(8375418e5),
        ShipName: 'Ernst Handel', ShipCity: 'Graz', ShipAddress: 'Kirchgasse 6',
        ShipRegion: 'CJ', Mask: '2345', ShipPostalCode: '8010', ShipCountry: 'Austria', Freight: 140.51, Verified: !0
    },
    {
        OrderID: 10259, CustomerID: 'CENTC', Role: 'Admin', EmployeeID: 4, OrderDate: new Date(8376282e5),
        ShipName: 'Centro comercial Moctezuma', ShipCity: 'México D.F.', ShipAddress: 'Sierras de Granada 9993',
        ShipRegion: 'CJ', Mask: '3456', ShipPostalCode: '05022', ShipCountry: 'Mexico', Freight: 3.25, Verified: !1
    },
    {
        OrderID: 10260, CustomerID: 'OTTIK', Role: 'Admin', EmployeeID: 4, OrderDate: new Date(8377146e5),
        ShipName: 'Ottilies Käseladen', ShipCity: 'Köln', ShipAddress: 'Mehrheimerstr. 369',
        ShipRegion: 'CJ', Mask: '4567', ShipPostalCode: '50739', ShipCountry: 'Germany', Freight: 55.09, Verified: !0
    },
    {
        OrderID: 10261, CustomerID: 'QUEDE', Role: 'Manager', EmployeeID: 4, OrderDate: new Date(8377146e5),
        ShipName: 'Que Delícia', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua da Panificadora, 12',
        ShipRegion: 'RJ', Mask: '5678', ShipPostalCode: '02389-673', ShipCountry: 'Brazil', Freight: 3.05, Verified: !1
    },
    {
        OrderID: 10262, CustomerID: 'RATTC', Role: 'Employee', EmployeeID: 8, OrderDate: new Date(8379738e5),
        ShipName: 'Rattlesnake Canyon Grocery', ShipCity: 'Albuquerque', ShipAddress: '2817 Milton Dr.',
        ShipRegion: 'NM', Mask: '6789', ShipPostalCode: '87110', ShipCountry: 'USA', Freight: 48.29, Verified: !0
    }
];
export let data: Object[] = [
    {
        OrderID: 10248, CustomerID: 'VINET', Role: 'Admin', EmployeeID: 5, OrderDate: new Date(8364186e5),
        ShipName: 'Vins et alcools Chevalier', ShipCity: 'Reims', ShipAddress: '59 rue de l Abbaye',
        ShipRegion: 'CJ', Mask: '1111', ShipPostalCode: '51100', ShipCountry: 'France', Freight: 32.38, Verified: !0
    },
    {
        OrderID: 10249, CustomerID: 'TOMSP', Role: 'Employee', EmployeeID: 6, OrderDate: new Date(836505e6),
        ShipName: 'Toms Spezialitäten', ShipCity: 'Münster', ShipAddress: 'Luisenstr. 48',
        ShipRegion: 'CJ', Mask: '2222', ShipPostalCode: '44087', ShipCountry: 'Germany', Freight: 11.61, Verified: !1
    },
    {
        OrderID: 10250, CustomerID: 'HANAR', Role: 'Admin', EmployeeID: 4, OrderDate: new Date(8367642e5),
        ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67',
        ShipRegion: 'RJ', Mask: '3333', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 65.83, Verified: !0
    },
    {
        OrderID: 10251, CustomerID: 'VICTE', Role: 'Manager', EmployeeID: 3, OrderDate: new Date(8367642e5),
        ShipName: 'Victuailles en stock', ShipCity: 'Lyon', ShipAddress: '2, rue du Commerce',
        ShipRegion: 'CJ', Mask: '4444', ShipPostalCode: '69004', ShipCountry: 'France', Freight: 41.34, Verified: !0
    },
    {
        OrderID: 10252, CustomerID: 'SUPRD', Role: 'Manager', EmployeeID: 4, OrderDate: new Date(8368506e5),
        ShipName: 'Suprêmes délices', ShipCity: 'Charleroi', ShipAddress: 'Boulevard Tirou, 255',
        ShipRegion: 'CJ', Mask: '5555', ShipPostalCode: 'B-6000', ShipCountry: 'Belgium', Freight: 51.3, Verified: !0
    },
    {
        OrderID: 10253, CustomerID: 'HANAR', Role: 'Admin', EmployeeID: 3, OrderDate: new Date(836937e6),
        ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67',
        ShipRegion: 'RJ', Mask: '6666', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 58.17, Verified: !0
    },
    {
        OrderID: 10254, CustomerID: 'CHOPS', Role: 'Employee', EmployeeID: 5, OrderDate: new Date(8370234e5),
        ShipName: 'Chop-suey Chinese', ShipCity: 'Bern', ShipAddress: 'Hauptstr. 31',
        ShipRegion: 'CJ',  Mask: '7777', ShipPostalCode: '3012', ShipCountry: 'Switzerland', Freight: 22.98, Verified: !1
    },
    {
        OrderID: 10255, CustomerID: 'RICSU', Role: 'Admin', EmployeeID: 9, OrderDate: new Date(8371098e5),
        ShipName: 'Richter Supermarkt', ShipCity: 'Genève', ShipAddress: 'Starenweg 5',
        ShipRegion: 'CJ', Mask: '8888', ShipPostalCode: '1204', ShipCountry: 'Switzerland', Freight: 148.33, Verified: !0
    },
    {
        OrderID: 10256, CustomerID: 'WELLI', Role: 'Employee', EmployeeID: 3, OrderDate: new Date(837369e6),
        ShipName: 'Wellington Importadora', ShipCity: 'Resende', ShipAddress: 'Rua do Mercado, 12',
        ShipRegion: 'SP', Mask: '9999', ShipPostalCode: '08737-363', ShipCountry: 'Brazil', Freight: 13.97, Verified: !1
    },
    {
        OrderID: 10257, CustomerID: 'HILAA', Role: 'Admin', 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', Mask: '1234', ShipPostalCode: '5022', ShipCountry: 'Venezuela', Freight: 81.91, Verified: !0
    },
    {
        OrderID: 10258, CustomerID: 'ERNSH', Role: 'Manager', EmployeeID: 1, OrderDate: new Date(8375418e5),
        ShipName: 'Ernst Handel', ShipCity: 'Graz', ShipAddress: 'Kirchgasse 6',
        ShipRegion: 'CJ', Mask: '2345', ShipPostalCode: '8010', ShipCountry: 'Austria', Freight: 140.51, Verified: !0
    },
    {
        OrderID: 10259, CustomerID: 'CENTC', Role: 'Admin', EmployeeID: 4, OrderDate: new Date(8376282e5),
        ShipName: 'Centro comercial Moctezuma', ShipCity: 'México D.F.', ShipAddress: 'Sierras de Granada 9993',
        ShipRegion: 'CJ', Mask: '3456', ShipPostalCode: '05022', ShipCountry: 'Mexico', Freight: 3.25, Verified: !1
    },
    {
        OrderID: 10260, CustomerID: 'OTTIK', Role: 'Admin', EmployeeID: 4, OrderDate: new Date(8377146e5),
        ShipName: 'Ottilies Käseladen', ShipCity: 'Köln', ShipAddress: 'Mehrheimerstr. 369',
        ShipRegion: 'CJ', Mask: '4567', ShipPostalCode: '50739', ShipCountry: 'Germany', Freight: 55.09, Verified: !0
    },
    {
        OrderID: 10261, CustomerID: 'QUEDE', Role: 'Manager', EmployeeID: 4, OrderDate: new Date(8377146e5),
        ShipName: 'Que Delícia', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua da Panificadora, 12',
        ShipRegion: 'RJ', Mask: '5678', ShipPostalCode: '02389-673', ShipCountry: 'Brazil', Freight: 3.05, Verified: !1
    },
    {
        OrderID: 10262, CustomerID: 'RATTC', Role: 'Employee', EmployeeID: 8, OrderDate: new Date(8379738e5),
        ShipName: 'Rattlesnake Canyon Grocery', ShipCity: 'Albuquerque', ShipAddress: '2817 Milton Dr.',
        ShipRegion: 'NM', Mask: '6789', ShipPostalCode: '87110', ShipCountry: 'USA', Freight: 48.29, Verified: !0
    }];

  • The Grid state persistence feature does not support the changeDataSource method.
  • In this document, the above sample uses local data for the changeDataSource method. For remote data sources, refer to the FlexibleData resource.

Setting custom headers using a custom adaptor

Custom headers in HTTP requests are used to send additional information such as authentication tokens, API keys, or metadata required by the server. These headers improve security and enable better control over data communication. In the Syncfusion® React Grid, custom headers can be added when making API requests, ensuring that each request carries the necessary information for server-side validation and processing.

This method is particularly useful when integrating the Grid with authenticated APIs, where requests must include authorization tokens or other security credentials to ensure secure access.

To achieve this, extend the WebApiAdaptor to create a custom adaptor. The beforeSend method in the custom adaptor enables modification of request headers before sending them to the server, ensuring that every request from the Grid includes the required headers.

The following example demonstrates setting custom headers using the custom adaptor in Syncfusion® React Grid.

import { ColumnDirective, ColumnsDirective, Grid, GridComponent, Page, Inject } from '@syncfusion/ej2-react-grids';
import * as React from 'react';
import { DataManager, WebApiAdaptor } from '@syncfusion/ej2-data';
import { CustomAdaptor } from './CustomAdaptor';
function App() {
  const data = new DataManager({
    adaptor: new CustomAdaptor(),
    url: 'https://services.syncfusion.com/react/production/api/Orders',
  });
  return <div>
    <GridComponent dataSource={data} height={280} allowPaging={true}>
      <ColumnsDirective>
        <ColumnDirective field="OrderID" headerText="Order ID" width="150" textAlign='Right'/>
        <ColumnDirective field="CustomerID" headerText="Customer ID" width="150"/>
        <ColumnDirective field="EmployeeID" headerText="Employee ID" width="150" textAlign='Right'/>
        <ColumnDirective field="Freight" headerText="Freight" width="150" textAlign='Right' format="C2"/>
        <ColumnDirective field="ShipCountry" headerText="ShipCountry" width="150"/>
      </ColumnsDirective>
      <Inject services={[Page]} />
    </GridComponent>
  </div>
};
export default App;
import { ColumnDirective, ColumnsDirective, Grid, GridComponent, Page, Inject } from '@syncfusion/ej2-react-grids';
import * as React from 'react';
import { DataManager, WebApiAdaptor } from '@syncfusion/ej2-data';
import { CustomAdaptor } from './CustomAdaptor';
function App() {
  const data = new DataManager({
    adaptor: new CustomAdaptor(),
    url: 'https://services.syncfusion.com/react/production/api/Orders',
  });
  return <div>
    <GridComponent dataSource={data} height={280} allowPaging={true}>
      <ColumnsDirective>
        <ColumnDirective field="OrderID" headerText="Order ID" width="150" textAlign='Right'/>
        <ColumnDirective field="CustomerID" headerText="Customer ID" width="150"/>
        <ColumnDirective field="EmployeeID" headerText="Employee ID" width="150" textAlign='Right'/>
        <ColumnDirective field="Freight" headerText="Freight" width="150" textAlign='Right' format="C2"/>
        <ColumnDirective field="ShipCountry" headerText="ShipCountry" width="150"/>
      </ColumnsDirective>
      <Inject services={[Page]} />
    </GridComponent>
  </div>
};
export default App;
import { WebApiAdaptor } from '@syncfusion/ej2-data';
export class CustomAdaptor extends WebApiAdaptor {
  beforeSend(args, xhr, settings) {
    xhr.withCredentials = true;
    super.beforeSend(args, xhr, settings);
    xhr.headers.set('Syncfusion', true); // Assign custom headers here.
  }
}
import { WebApiAdaptor } from '@syncfusion/ej2-data';
export class CustomAdaptor extends WebApiAdaptor {
  beforeSend(args:any, xhr:any, settings:any) {
    xhr.withCredentials = true;
    super.beforeSend(args, xhr, settings);
    xhr.headers.set('Syncfusion', true); // Assign custom headers here.
  }
}

Prevent conversion to local time zone for date columns

By default, Syncfusion® React Grid converts date values to the client system’s local time zone. In some scenarios, it is necessary to display the original date as received from the server without timezone conversion.

To prevent timezone conversion for a date column, use the DataUtil.serverTimezoneOffset property. Setting this property to “0” ensures that dates remain in the original server-provided format without conversion to the local timezone.

The following example demonstrates preventing local time zone conversion for date columns by using the DataUtil.serverTimezoneOffset property:

import { ColumnDirective, ColumnsDirective, GridComponent } from '@syncfusion/ej2-react-grids';
import * as React from 'react';
import { DataManager, WebApiAdaptor } from "@syncfusion/ej2-data";
import { DropDownListComponent } from "@syncfusion/ej2-react-dropdowns";
import { CheckBoxComponent } from "@syncfusion/ej2-react-buttons";
import { DataUtil } from "@syncfusion/ej2-data";

function App() {
  let grid;
  let selectedTimezone = -12;
  let timezoneCheckboxRef;
  const hostUrl = "https://services.syncfusion.com/react/production/";
  const data = new DataManager({ url: hostUrl + 'api/Orders', adaptor: new WebApiAdaptor });
  const field = { text: 'text', value: 'value' };
  const timeZones = [
    { value: -12, text: "-12:00 UTC" },
    { value: -11, text: "-11:00 UTC" },
    { value: -10, text: "-10:00 UTC" },
    { value: -9, text: "-09:00 UTC" },
    { value: -8, text: "-08:00 UTC" },
    { value: -7, text: "-07:00 UTC" },
    { value: -6, text: "-06:00 UTC" },
    { value: -5, text: "-05:00 UTC" },
    { value: -4, text: "-04:00 UTC" },
    { value: -3, text: "-03:00 UTC" },
    { value: -2, text: "-02:00 UTC" },
    { value: -1, text: "-01:00 UTC" },
    { value: 0, text: "+00:00 UTC" },
    { value: 1, text: "+01:00 UTC" },
    { value: 2, text: "+02:00 UTC" },
    { value: 3, text: "+03:00 UTC" },
    { value: 4, text: "+04:00 UTC" },
    { value: 5, text: "+05:00 UTC" },
    { value: 5.5, text: "+05:30 UTC" },
    { value: 6, text: "+06:00 UTC" },
    { value: 7, text: "+07:00 UTC" },
    { value: 8, text: "+08:00 UTC" },
    { value: 9, text: "+09:00 UTC" },
    { value: 10, text: "+10:00 UTC" },
    { value: 11, text: "+11:00 UTC" },
    { value: 12, text: "+12:00 UTC" },
    { value: 13, text: "+13:00 UTC" },
    { value: 14, text: "+14:00 UTC" },
  ];

  const onTimezoneChange = (event) => {
    selectedTimezone=(Number(event.itemData.value));
    grid.freezeRefresh();
  };
  
  const onCheckboxChange = (event) => {
    grid.freezeRefresh();
  };

  const load= (event) => {
    DataUtil.serverTimezoneOffset = timezoneCheckboxRef.checked ? 0 : selectedTimezone;
  }
  return (
    <div>
      <div style=>
        <label style=>Select Timezone:</label>
        <DropDownListComponent
          id="timezone"
          width="150px"
          dataSource={timeZones}
          value={selectedTimezone}
          change={onTimezoneChange}
          fields={field}
          index={0}
        />
      </div>
      <div style=>
        <CheckBoxComponent
          ref ={checkbox=>timezoneCheckboxRef=checkbox}
          label="Prevent Timezone Conversion"
          change={onCheckboxChange}
        />
      </div>
      <GridComponent ref={g => grid = g} dataSource={data} load={load} height={280}>
        <ColumnsDirective>
          <ColumnDirective field="OrderID" headerText="Order ID" textAlign="Right" width={120} />
          <ColumnDirective field="CustomerID" headerText="Customer ID" width={140} />
          <ColumnDirective field="Freight" headerText="Freight" textAlign="Right" format="C" width={120} />
          <ColumnDirective field="OrderDate" headerText="Order Date" textAlign="Right" width={140} />
        </ColumnsDirective>
      </GridComponent>
    </div>
  );
};
export default App;
import { ColumnDirective, ColumnsDirective, GridComponent } from '@syncfusion/ej2-react-grids';
import * as React from 'react';
import { DataManager, WebApiAdaptor } from "@syncfusion/ej2-data";
import { DropDownListComponent } from "@syncfusion/ej2-react-dropdowns";
import { CheckBoxComponent } from "@syncfusion/ej2-react-buttons";
import { ChangeEventArgs } from '@syncfusion/ej2-dropdowns';
import { DataUtil } from "@syncfusion/ej2-data";
function App() {
  let grid: GridComponent | null;
  let selectedTimezone: number = -12;
  let timezoneCheckboxRef: CheckBoxComponent| null;
  const hostUrl = "https://services.syncfusion.com/react/production/";
  const data = new DataManager({ url: hostUrl + 'api/Orders', adaptor: new WebApiAdaptor });
  const field = { text: 'text', value: 'value' };
  const timeZones = [
    { value: -12, text: "-12:00 UTC" },
    { value: -11, text: "-11:00 UTC" },
    { value: -10, text: "-10:00 UTC" },
    { value: -9, text: "-09:00 UTC" },
    { value: -8, text: "-08:00 UTC" },
    { value: -7, text: "-07:00 UTC" },
    { value: -6, text: "-06:00 UTC" },
    { value: -5, text: "-05:00 UTC" },
    { value: -4, text: "-04:00 UTC" },
    { value: -3, text: "-03:00 UTC" },
    { value: -2, text: "-02:00 UTC" },
    { value: -1, text: "-01:00 UTC" },
    { value: 0, text: "+00:00 UTC" },
    { value: 1, text: "+01:00 UTC" },
    { value: 2, text: "+02:00 UTC" },
    { value: 3, text: "+03:00 UTC" },
    { value: 4, text: "+04:00 UTC" },
    { value: 5, text: "+05:00 UTC" },
    { value: 5.5, text: "+05:30 UTC" },
    { value: 6, text: "+06:00 UTC" },
    { value: 7, text: "+07:00 UTC" },
    { value: 8, text: "+08:00 UTC" },
    { value: 9, text: "+09:00 UTC" },
    { value: 10, text: "+10:00 UTC" },
    { value: 11, text: "+11:00 UTC" },
    { value: 12, text: "+12:00 UTC" },
    { value: 13, text: "+13:00 UTC" },
    { value: 14, text: "+14:00 UTC" },
  ];

  const onTimezoneChange = (event: ChangeEventArgs) => {
    selectedTimezone=(Number(event.itemData.value));
    grid.freezeRefresh();
  };
  
  const onCheckboxChange = (event: ChangeEventArgs) => {
    grid.freezeRefresh();
  };

  const load= (event: object) => {
    DataUtil.serverTimezoneOffset = timezoneCheckboxRef.checked ? 0 : selectedTimezone;
  }
  
  return (
    <div>
      <div style=>
        <label style=>Select Timezone:</label>
        <DropDownListComponent
          id="timezone"
          width="150px"
          dataSource={timeZones}
          value={selectedTimezone}
          change={onTimezoneChange}
          fields={field}
          index={0}
        />
      </div>
      <div style=>
        <CheckBoxComponent
          ref ={checkbox=>timezoneCheckboxRef=checkbox}
          label="Prevent Timezone Conversion"
          change={onCheckboxChange}
        />
      </div>
      <GridComponent ref={g => grid = g} dataSource={data} load={load} height={280}>
        <ColumnsDirective>
          <ColumnDirective field="OrderID" headerText="Order ID" textAlign="Right" width={120} />
          <ColumnDirective field="CustomerID" headerText="Customer ID" width={140} />
          <ColumnDirective field="Freight" headerText="Freight" textAlign="Right" format="C" width={120} />
          <ColumnDirective field="OrderDate" headerText="Order Date" textAlign="Right" width={140} />
        </ColumnsDirective>
      </GridComponent>
    </div>
  );
};
export default App;