Search results

Columns

The column definitions are used as the dataSource schema in the Grid. This plays a vital role in rendering column values in the required format. The grid operations such as sorting, filtering and grouping etc. are performed based on column definitions. The field property of the columns is necessary to map the data source values in Grid columns.

  1. If the column with field is not in the dataSource, then the column values will be displayed as empty.
  2. If the field name contains “dot” operator then it is considered as complex binding.

Auto generation

The columns are automatically generated when columns declaration is empty or undefined while initializing the grid. All the columns in the dataSource are bound as grid columns.

Source
Preview
index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GridComponent } from '@syncfusion/ej2-react-grids';

let data: Object[] = [
    { OrderID: 10248, CustomerID: 'VINET', EmployeeID: 5 },
    { OrderID: 10249, CustomerID: 'TOMSP', EmployeeID: 6 },
    { OrderID: 10250, CustomerID: 'HANAR', EmployeeID: 4 }];

class App extends React.Component<{}, {}>{
    render() {
        return <GridComponent dataSource={data}>
               </GridComponent>
    }
}
ReactDOM.render(<App />, document.getElementById('grid'));

How to set isPrimaryKey for auto generated columns when editing is enabled

Primary key can be defined in the declaration of column object of the grid. When we didn’t declare the columns, the grid will generate the columns automatically. For these auto generated columns, you can set isPrimaryKey column property as true by using the following ways,

If Primary key “column index” is known then refer the following code example

Source
Preview
index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GridComponent, Inject, Edit, EditSettingsModel } from '@syncfusion/ej2-react-grids';

let data: Object[] = [
    { OrderID: 10248, CustomerID: 'VINET', EmployeeID: 5 },
    { OrderID: 10249, CustomerID: 'TOMSP', EmployeeID: 6 },
    { OrderID: 10250, CustomerID: 'HANAR', EmployeeID: 4 }];

class App extends React.Component<{}, {}>{
    public dataBound(){
        var column = this.grid.columns[0];
        column.isPrimaryKey = 'true';
    }
    private grid: Grid;
    public editOptions: EditSettingsModel = { allowEditing: true, allowAdding: true, allowDeleting: true };
    render() {
        return <GridComponent dataSource={data} dataBound= { this.dataBound.bind(this)} editSettings={this.editOptions} ref={g => this.grid = g}>
        <Inject services={[Edit]} />
               </GridComponent>
    }
}
ReactDOM.render(<App />, document.getElementById('grid'));

If Primary key “column fieldname” is known then you can get the column by using var column = grid.getColumnByField('OrderID') and then set primary key by defining column.isPrimaryKey = 'true'

Set column options to auto generated columns

You can set column options such as format, width to the auto generated columns by using dataBound event of the grid.

In the below example, width is set for OrderID column, date type is set for OrderDate column and numeric type is set for Freight column.

Source
Preview
index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GridComponent } from '@syncfusion/ej2-react-grids';

let data = [
            { OrderID: 10248, CustomerID: 'VINET', Freight: 32.3800, OrderDate: "1996-07-02T00:00:00.000Z" },
            { OrderID: 10249, CustomerID: 'TOMSP', Freight: 32.3800, OrderDate: "1996-07-19T00:00:00.000Z" },
            { OrderID: 10250, CustomerID: 'HANAR', Freight: 32.3800, OrderDate: "1996-07-22T00:00:00.000Z" }];

class App extends React.Component<{}, {}>{
    public dataBound(){
    for (var i = 0; i < this.grid.columns.length; i++) {
            this.grid.columns[0].width = 120;
            if(this.grid.columns[i].field === "OrderDate"){
                this.grid.columns[i].type="date";
            }
            if (this.grid.columns[i].type === "date") {
                this.grid.columns[i].format = { type: "date", format: "dd/MM/yyyy" };
            }
            this.grid.columns[2].format = "P2";
        }
        this.grid.refreshColumns();
    }
    private grid: Grid;
    render() {
        return <GridComponent dataSource={data} dataBound= { this.dataBound.bind(this)} ref={g => this.grid = g}>
               </GridComponent>
    }
}
ReactDOM.render(<App />, document.getElementById('grid'));

Header Text

By default, column header title is displayed from column field value. To override the default header title by defining headerText value.

Source
Preview
index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GridComponent, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-grids';
import { data } from '../datasource.ts';

class App extends React.Component<{}, {}>{
    public data: Object[] = data;
    render() {
        return <GridComponent dataSource={this.data} height={315}>
                <ColumnsDirective>
                    <ColumnDirective field='OrderID' headerText='Order ID' width='120' textAlign="Right"></ColumnDirective>
                    <ColumnDirective field='CustomerID' headerText='Customer ID' width='150'></ColumnDirective>
                    <ColumnDirective field='ShipCity' headerText='Ship City' width='150'></ColumnDirective>
                    <ColumnDirective field='ShipName' headerText='Ship Name' width='150'></ColumnDirective>
                </ColumnsDirective>
               </GridComponent>
    }
}
ReactDOM.render(<App />, document.getElementById('grid'));
  • If both the field and headerText are not defined in the column, the column renders with “empty” header text.

Format

To format cell values based on specific culture, use the columns.format property. The grid uses Internalization library to format number and date values.

Source
Preview
index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GridComponent, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-grids';
import { data } from '../datasource.ts';

class App extends React.Component<{}, {}>{
    public data: Object[] = data;
    render() {
        return <GridComponent dataSource={this.data} height={315}>
                <ColumnsDirective>
                 <ColumnDirective field='OrderID' width='100' textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='CustomerID' width='100'></ColumnDirective>
                 <ColumnDirective field='Freight' width='100' format="C2" textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='OrderDate' width='140' format="yMd" textAlign="Right"></ColumnDirective>
                </ColumnsDirective>
               </GridComponent>
    }
}
ReactDOM.render(<App />, document.getElementById('grid'));

By default, the number and date values are formatted in en-US locale.

Number formatting

The number or integer values can be formatted using the below format strings.

Format Description
N Denotes numeric type.
C Denotes currency type.
P Denotes percentage type

Please refer to the link to know more about Number formatting format.

Date formatting

You can format date values either using built-in date format string or custom format string.

For built-in date format you can specify columns.format property as string (Example: yMd). Please refer to the link to know more about Date formatting.

You can also use custom format string to format the date values. Some of the custom formats and the formatted date values are given in the below table.

Format Formatted value
{ type:‘date’, format:‘dd/MM/yyyy’ } 04/07/1996
{ type:‘date’, format:‘dd.MM.yyyy’ } 04.07.1996
{ type:‘date’, skeleton:‘short’ } 7/4/96
{ type: ‘dateTime’, format: ‘dd/MM/yyyy hh:mm a’ } 04/07/1996 12:00 AM
{ type: ‘dateTime’, format: ‘MM/dd/yyyy hh:mm:ss a’ } 07/04/1996 12:00:00 AM
Source
Preview
index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GridComponent, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-grids';
import { data } from '../datasource.ts';

class App extends React.Component<{}, {}>{
    public data: Object[] = data;
    public formatOption: Object = {type:'date', format:'dd/MM/yyyy'};
    public shipFormat: Object = { type: 'dateTime', format: 'dd/MM/yyyy hh:mm a' };
    render() {
        return <GridComponent dataSource={this.data} height={315}>
                <ColumnsDirective>
                 <ColumnDirective field='OrderID' width='100' textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='Freight' width='100' format="C2" textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='OrderDate' width='140' textAlign="Right" format={this.formatOption} ></ColumnDirective>
                 <ColumnDirective field='OrderDate' headerText='Ship Date' width='180' textAlign="Right" format={this.shipFormat} ></ColumnDirective>
                </ColumnsDirective>
               </GridComponent>
    }
}
ReactDOM.render(<App />, document.getElementById('grid'));

Visibility

You can hide any particular column in Grid before rendering by defining visible property as false. In the below sample ShipCity column is defined as visible false.

Source
Preview
index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GridComponent, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-grids';
import { data } from '../datasource.ts';

class App extends React.Component<{}, {}>{
    public data: Object[] = data;
    private grid: Grid;
    render() {
        return <GridComponent dataSource={this.data} height={315} >
                <ColumnsDirective>
                 <ColumnDirective field='OrderID' headertext= 'Order ID' width='150'></ColumnDirective>
                 <ColumnDirective field='CustomerID' headertext= 'Customer ID' width='150'></ColumnDirective>
                 <ColumnDirective field='ShipName' headertext= 'Ship Name' width='150'></ColumnDirective>
                 <ColumnDirective field='ShipAddress' headertext= 'Ship Address' width='150' format="yMd"></ColumnDirective>
                 <ColumnDirective field='ShipCity' headertext= 'Ship City' visible={false} width='150' ></ColumnDirective>
                </ColumnsDirective>
               </GridComponent>
    }
}
ReactDOM.render(<App />, document.getElementById('grid'));

AutoFit specific columns

The autoFitColumns method resizes the column to fit the widest cell’s content without wrapping. You can autofit a specific columns at initial rendering by invoking the autoFitColumns method in dataBound event.

To use the autoFilColumns method, inject the Resize module in the grid.

Source
Preview
index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GridComponent, Inject, Resize, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-grids';
import { data } from '../datasource.ts';

class App extends React.Component<{}, {}>{
    public data: Object[] = data;
    public dataBound(){
    this.grid.autoFitColumns(['ShipName', 'ShipAddress']);
    }
    private grid: Grid;
    render() {
        return <GridComponent dataSource={this.data} height={315} dataBound= { this.dataBound.bind(this)} ref={g => this.grid = g}>
                <Inject services={[Resize]}></Inject>
                <ColumnsDirective>
                 <ColumnDirective field='OrderID' headertext= 'Order ID' width='150'></ColumnDirective>
                 <ColumnDirective field='CustomerID' headertext= 'Customer ID' width='150'></ColumnDirective>
                 <ColumnDirective field='ShipName' headertext= 'Ship Name' width='150'></ColumnDirective>
                 <ColumnDirective field='ShipAddress' headertext= 'Ship Address' width='150' format="yMd"></ColumnDirective>
                 <ColumnDirective field='ShipCity' headertext= 'Ship City' width='150' ></ColumnDirective>
                </ColumnsDirective>
               </GridComponent>
    }
}
ReactDOM.render(<App />, document.getElementById('grid'));

You can autofit all columns, by invoking autoFitColumns method without column name.

Reorder

Reordering can be done by drag and drop of a particular column header from one index to another index within the grid. To enable reordering, set the allowReordering to true.

To use reordering, inject the Reorder module in the grid.

Source
Preview
index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GridComponent, Inject, Reorder, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-grids';
import { data } from '../datasource.ts';

class App extends React.Component<{}, {}>{
    public data: Object[] = data;
    render() {
        return <GridComponent dataSource={this.data} allowReordering={true} height={315}>
                <Inject services={[Reorder]}></Inject>
                <ColumnsDirective>
                 <ColumnDirective field='OrderID' width='100' textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='CustomerID' width='100'></ColumnDirective>
                 <ColumnDirective field='Freight' width='100' format="C2" textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='OrderDate' width='140' format="yMd" textAlign="Right"></ColumnDirective>
                </ColumnsDirective>
               </GridComponent>
    }
}
ReactDOM.render(<App />, document.getElementById('grid'));

You can disable reordering a particular column by setting the columns.allowReordering to false.

Reorder Single Column

Grid have option to reorder Columns either by Interaction or by using the reorderColumns method. In the below sample, ShipCity column is reordered to last column position by using the method.

Source
Preview
index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { ButtonComponent } from '@syncfusion/ej2-react-buttons';
import { GridComponent, Inject, Reorder, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-grids';
import { data } from '../datasource.ts';

class App extends React.Component<{}, {}>{

    public reorder(){
       this.grid.reorderColumns('ShipCity','ShipName');
    }

    public data: Object[] = data;

    private grid: Grid;
    render() {
        return (<div>
        <ButtonComponent id='reorderSingleCols' value='reorder' onClick= { this.reorder.bind(this)}>Reorder Ship City to Last</ButtonComponent>
        <GridComponent dataSource={this.data} allowReordering={true} height={275} ref={g => this.grid = g}>
                <Inject services={[Reorder]}></Inject>
                <ColumnsDirective>
                 <ColumnDirective field='OrderID' width='100' textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='CustomerID' width='100'></ColumnDirective>
                 <ColumnDirective field='ShipCity' headertext= 'Ship City' width='100' textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='ShipRegion' headertext= 'Ship Region' width='100' textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='ShipName' headertext= 'Ship Name' width='150' textAlign="Right"></ColumnDirective>
                </ColumnsDirective>
               </GridComponent></div>)
    }
};
ReactDOM.render(<App />, document.getElementById('grid'));

Reorder Multiple Columns

User can reorder a single column at a time by Interaction. Sometimes we need to have reorder multiple columns at the same time, It can be achieved through programmatically by using reorderColumns method.

In the below sample, Ship City and Ship Region column is reordered to last column position.

Source
Preview
index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { ButtonComponent } from '@syncfusion/ej2-react-buttons';
import { GridComponent, Inject, Reorder, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-grids';
import { data } from '../datasource.ts';

class App extends React.Component<{}, {}>{

    public reorder(){
       this.grid.reorderColumns(['ShipCity','ShipRegion'],'ShipName');
    }

    public data: Object[] = data;

    private grid: Grid;
    render() {
        return (<div>
        <ButtonComponent id='reorderMultipleCols' value='reorder' onClick= { this.reorder.bind(this)}>Reorder Ship City and Ship Region to Last</ButtonComponent>
        <GridComponent dataSource={this.data} allowReordering={true} height={275} ref={g => this.grid = g}>
                <Inject services={[Reorder]}></Inject>
                <ColumnsDirective>
                 <ColumnDirective field='OrderID' width='100' textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='CustomerID' width='100'></ColumnDirective>
                 <ColumnDirective field='ShipCity' headertext= 'Ship City' width='100' textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='ShipRegion' headertext= 'Ship Region' width='100' textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='ShipName' headertext= 'Ship Name' width='150' textAlign="Right"></ColumnDirective>
                </ColumnsDirective>
               </GridComponent></div>)
    }
};
ReactDOM.render(<App />, document.getElementById('grid'));

Reorder Events

During the reorder action, the grid component triggers the below three events.

  1. The columnDragStart event triggers when column header element drag (move) starts.
  2. The columnDrag event triggers when column header element is dragged (moved) continuously.
  3. The columnDrop event triggers when a column header element is dropped on the target column.
Source
Preview
index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { ButtonComponent } from '@syncfusion/ej2-react-buttons';
import { GridComponent, Inject, Reorder, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-grids';
import { data } from '../datasource.ts';

class App extends React.Component<{}, {}>{

    public columnDrop(){
       alert('columnDrop event is Triggered');
    }
    public columnDragStart(){
       alert('columnDragStart event is Triggered');
    }
    public columnDrag(){
       alert('columnDrag event is Triggered');
    }

    public data: Object[] = data;

    private grid: Grid;
    render() {
        return (<div>
        <GridComponent dataSource={this.data} allowReordering={true} height={275} ref={g => this.grid = g}
        columnDragStart= { this.columnDragStart.bind(this)} columnDrag= { this.columnDrag.bind(this)} columnDrop= { this.columnDrop.bind(this)}>
                <Inject services={[Reorder]}></Inject>
                <ColumnsDirective>
                 <ColumnDirective field='OrderID' width='100' textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='CustomerID' width='100'></ColumnDirective>
                 <ColumnDirective field='ShipCity' headertext= 'Ship City' width='100' textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='ShipRegion' headertext= 'Ship Region' width='100' textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='ShipName' headertext= 'Ship Name' width='150' textAlign="Right"></ColumnDirective>
                </ColumnsDirective>
               </GridComponent></div>)
    }
};
ReactDOM.render(<App />, document.getElementById('grid'));

Lock Columns

You can lock columns by using column.lockColumn property. The locked columns will be moved to the first position. Also you can’t reorder its position.

In the below example, Ship City column is locked and its reordering functionality is disabled.

Source
Preview
index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GridComponent, Inject, Reorder, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-grids';
import { data } from '../datasource.ts';

class App extends React.Component<{}, {}>{
    public data: Object[] = data;
    public customAttributes: Object = {class: 'customcss'};
    render() {
        return <GridComponent dataSource={this.data} allowReordering={true} allowSelection={false} height={315}>
                <Inject services={[Reorder]}></Inject>
                <ColumnsDirective>
                 <ColumnDirective field='OrderID' width='100' textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='CustomerID' width='100'></ColumnDirective>
                 <ColumnDirective field='ShipCity' width='100' lockColumn= {true} customAttributes={this.customAttributes}></ColumnDirective>
                 <ColumnDirective field='ShipName' width='100'></ColumnDirective>
                 <ColumnDirective field='ShipPostalCode' width='120'></ColumnDirective>
                 <ColumnDirective field='ShipRegion' width='140'></ColumnDirective>
                </ColumnsDirective>
               </GridComponent>
    }
}
ReactDOM.render(<App />, document.getElementById('grid'));

Column Resizing

Columns width can be resized by clicking and dragging at the right edge of column header. While dragging, the width of respective column will be resized immediately. Each columns can be auto resized by double clicking at the right edge of column header. It will fit the width of that column based on widest cell content. To enable the column resize, set the allowResizing property to true.

To use the column resize, inject Resize module in the grid.

Source
Preview
index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GridComponent, Inject, Resize, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-grids';
import { data } from '../datasource.ts';

class App extends React.Component<{}, {}>{
    public data: Object[] = data;
    render() {
        return <GridComponent dataSource={this.data} allowResizing={true} height={315}>
                <Inject services={[Resize]}></Inject>
                <ColumnsDirective>
                 <ColumnDirective field='OrderID' headertext= 'Order ID' width='150' textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='CustomerID' headertext= 'Customer ID' width='150'></ColumnDirective>
                 <ColumnDirective field='Freight' width='150' format="C2" textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='OrderDate' headertext= 'Order ID' width='150' format="yMd" textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='ShipName' headertext= 'Ship Name' width='150' textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='ShipAddress' headertext= 'Ship Address' width='150' format="yMd" textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='ShipCountry' headertext= 'Ship Country' width='150'></ColumnDirective>
                 <ColumnDirective field='ShipCity' headertext= 'Ship City' width='150' textAlign="Right"></ColumnDirective>
                </ColumnsDirective>
               </GridComponent>
    }
}
ReactDOM.render(<App />, document.getElementById('grid'));

You can disable Resizing for a particular column, by specifying columns.allowResizing to false. In RTL mode, you can click and drag the left edge of header cell to resize the column.

Min and Max width

Columns can be restricted to resize in between minimum and maximum width by defining the columns->minWidth and columns->maxWidth.

In the below sample, OrderID, Ship Name and Ship Country columns are defined with minimum and maximum width.

Source
Preview
index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GridComponent, Inject, Resize, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-grids';
import { data } from '../datasource.ts';

class App extends React.Component<{}, {}>{
    public data: Object[] = data;
    render() {
        return <GridComponent dataSource={this.data} allowResizing={true} height={315}>
                <Inject services={[Resize]}></Inject>
                <ColumnsDirective>
                 <ColumnDirective field='OrderID' headertext= 'Order Id' minWidth= '100' width='150' maxWidth='250' textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='CustomerID' headertext= 'Customer ID' width='150'></ColumnDirective>
                 <ColumnDirective field='Freight' width='150' format="C2" textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='OrderDate' headertext= 'Order Date' width='120' format="yMd" textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='ShipName' headertext= 'Ship Name' minWidth= '120' width='150' maxWidth='200' textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='ShipAddress' headertext= 'Ship Address' width='150' format="yMd" textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='ShipCountry' headertext= 'Ship Country' minWidth= '150' width='180' maxWidth='300' ></ColumnDirective>
                 <ColumnDirective field='ShipCity' headertext= 'Ship City' width='150' textAlign="Right"></ColumnDirective>
                </ColumnsDirective>
               </GridComponent>
    }
}
ReactDOM.render(<App />, document.getElementById('grid'));

Resize Stacked Column

Stacked columns can be resized by clicking and dragging the right edge of the stacked column header. While dragging, the width of the respective child columns will be resized at the same time. You can disable resize for any particular stacked column by setting allowResizing as false to its columns.

In this example, we have disabled resize for Ship City column.

Source
Preview
index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GridComponent, Inject, Resize, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-grids';
import { data } from '../datasource.ts';

class App extends React.Component<{}, {}>{
    public data: Object[] = data;
    render() {
        return <GridComponent dataSource={this.data} allowResizing={true} height={315}>
                <Inject services={[Resize]}></Inject>
                <ColumnsDirective>
                    <ColumnDirective field='OrderID' headerText='Order ID' width='100' textAlign='Right'></ColumnDirective>
                    <ColumnDirective columns={[{ field: 'OrderDate', headerText: 'Order Date', format: 'yMd', width: 120, textAlign: 'Right' }, { field: 'Freight', headerText: 'Freight ($)', width: 100, format: 'C1', textAlign: 'Right' }]} headerText='Order Details' ></ColumnDirective>
                    <ColumnDirective columns={[{ field: 'ShipCity', headerText: 'Ship City', width: 120 }, { field: 'ShipCountry', headerText: 'Ship Country', width: 120 }]} headerText='Ship Details' />
                </ColumnsDirective>
               </GridComponent>
    }
}
ReactDOM.render(<App />, document.getElementById('grid'));

Touch Interaction

When you tap at the right edge of header cell, a floating handler will be visible over the right border of column. To resize the column, tap and drag the floating handler as much you need. You can also autoFit a column by using the Column menu of the grid.

The following screenshot represents the column resizing in the touch device.

Touch Interaction

Resizing Events

During the resizing action, the grid component triggers the below three events.

  1. The resizeStart event triggers when column resize starts.
  2. The resizing event triggers when column header element is dragged (moved) continuously..
  3. The resizeStop event triggers when column resize ends.
Source
Preview
index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GridComponent, Inject, Resize, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-grids';
import { data } from '../datasource.ts';

class App extends React.Component<{}, {}>{
    public data: Object[] = data;
    public resizeStart(){
       alert('resizeStart event is Triggered');
    }
    public resizing(){
       alert('resizing event is Triggered');
    }
    public resizeStop(){
       alert('resizeStop event is Triggered');
    }
    render() {
        return <GridComponent dataSource={this.data} allowResizing={true} height={315}
        resizeStart= { this.resizeStart.bind(this)} resizing= { this.resizing.bind(this)} resizeStop= { this.resizeStop.bind(this)}>
                <Inject services={[Resize]}></Inject>
                <ColumnsDirective>
                 <ColumnDirective field='OrderID' headertext= 'Order ID' width='150' textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='CustomerID' headertext= 'Customer ID' width='150'></ColumnDirective>
                 <ColumnDirective field='Freight' width='150' format="C2" textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='OrderDate' headertext= 'Order ID' width='150' format="yMd" textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='ShipName' headertext= 'Ship Name' width='150' textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='ShipAddress' headertext= 'Ship Address' width='150' format="yMd" textAlign="Right"></ColumnDirective>
                 <ColumnDirective field='ShipCountry' headertext= 'Ship Country' width='150'></ColumnDirective>
                 <ColumnDirective field='ShipCity' headertext= 'Ship City' width='150' textAlign="Right"></ColumnDirective>
                </ColumnsDirective>
               </GridComponent>
    }
}
ReactDOM.render(<App />, document.getElementById('grid'));

Column Template

The column template has options to display custom element instead of a field value in the column.

Source
Preview
index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GridComponent, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-grids';
import { employeeData } from '../datasource.ts';

class App extends React.Component<{}, {}>{

    public gridTemplate(props): any {
        var src = props.EmployeeID + '.png';
        return (<div className='image'>
            <img src={src} alt={props.EmployeeID} />
        </div>);
    }

    public template: any = this.gridTemplate;

    render() {
        return <GridComponent dataSource={employeeData} height={315}>
                    <ColumnsDirective>
                        <ColumnDirective headerText='Employee Image' width='180' template={this.template} textAlign='Center' />
                        <ColumnDirective field='EmployeeID' headerText='Employee ID' width='125' textAlign='Right' />
                        <ColumnDirective field='FirstName' headerText='Name' width='120' />
                        <ColumnDirective field='Title' headerText='Title' width='170' />
                        <ColumnDirective field='HireDate' headerText='Hire Date' width='135' format='yMd' textAlign='Right' />
                        <ColumnDirective field='ReportsTo' headerText='Reports To' width='120' textAlign='Right' />
                    </ColumnsDirective>
        </GridComponent>
    }
};
ReactDOM.render(<App />, document.getElementById('grid'));

Using condition template

You can render the template elements based on condition.

In the following code, checkbox is rendered based on Discontinued field value.

    public gridTemplate(props): any {
        if(props.Discontinued){
       return (<div class="template_checkbox">
                <input type="checkbox" checked/>
            </div>);
        }else{
             return (<div class="template_checkbox">
                <input type="checkbox"/>
            </div>);
        }
    }
Source
Preview
index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GridComponent, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-grids';
import { productData } from '../datasource.ts';

class App extends React.Component<{}, {}>{

    public gridTemplate(props): any {
        if(props.Discontinued){
       return (<div class="template_checkbox">
                <input type="checkbox" checked/>
            </div>);
        }else{
             return (<div class="template_checkbox">
                <input type="checkbox"/>
            </div>);
        }
    }

    public template: any = this.gridTemplate;

    render() {
        return <GridComponent dataSource={productData} height={315}>
                    <ColumnsDirective>
                        <ColumnDirective headerText='Discontinued' width='180' template={this.template} textAlign='Center' />
                        <ColumnDirective field='ProductID' headerText='Product ID' width='125' />
                        <ColumnDirective field='ProductName' headerText='Product Name' width='120' />
                        <ColumnDirective field='SupplierID' headerText='Supplier ID' width='170' />
                        <ColumnDirective field='UnitPrice' headerText='Unit Price' width='135' />
                    </ColumnsDirective>
        </GridComponent>
    }
};
ReactDOM.render(<App />, document.getElementById('grid'));

Column Type

Column type can be specified using the columns.type property. It specifies the type of the data the column bounded.

If the format is defined for a column, the column uses type to select the appropriate format option (number or date).

Grid column supports the following types:

  • string
  • number
  • boolean
  • date
  • datetime

If the type is not defined, then it will be determined from the first record of the dataSource. Incase if the first record of the dataSource is null/blank value for a column then it is necessary to define the type for that column.

Column chooser

The column chooser has options to show or hide columns dynamically. It can be enabled by defining the showColumnChooser as true.

To use the column chooser, inject the ColumnChooser module in the grid.

Source
Preview
index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GridComponent, Inject, ColumnsDirective, ColumnDirective, Toolbar, ToolbarItems, ColumnChooser } from '@syncfusion/ej2-react-grids';
import { data } from './datasource';

class App extends React.Component<{}, {}>{
    public toolbarOptions : ToolbarItems[] = ['ColumnChooser'];
    render(){
        return <GridComponent  dataSource={data} toolbar={this.toolbarOptions} height={272} showColumnChooser={true} >
                   <ColumnsDirective>
                    <ColumnDirective field='OrderID' headerText='Order ID' width='120' textAlign='Right'></ColumnDirective>
                    <ColumnDirective field='CustomerID' headerText='Customer ID' width='150' showInColumnChooser={false} >
                    </ColumnDirective>
                    <ColumnDirective field='Freight' width='100' format='C2' textAlign='Right'></ColumnDirective>
                    <ColumnDirective field='OrderDate' width='140' format='yMd' textAlign='Right'></ColumnDirective>
                    <ColumnDirective field='ShipCity' headerText='Ship City' width='150'></ColumnDirective>
                    <ColumnDirective field='ShipName' headerText='Ship Name' width='150' visible = {false} >
                    </ColumnDirective>
                </ColumnsDirective>
                <Inject services={[Toolbar, ColumnChooser]}/>
            </GridComponent >
        }
};
ReactDOM.render(<App />, document.getElementById('grid'));

You can hide the column names in column chooser by defining the columns.showInColumnChooser as false.

Open column chooser by external button

The Column chooser can be displayed on a page through external button by invoking the openColumnChooser method with X and Y axis positions.

Source
Preview
index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { ButtonComponent } from '@syncfusion/ej2-react-buttons';
import { Grid, GridComponent, ColumnsDirective, ColumnDirective , ColumnChooser, Inject } from '@syncfusion/ej2-react-grids';
import { data } from '../datasource.ts';

class App extends React.Component<{}, {}>{
    public show() {
        this.grid.columnChooserModule.openColumnChooser(200,50); //give X and Y axis
    }

    private grid: Grid;
    render() {
        return (<div>
        <ButtonComponent value='Show' cssClass= 'e-flat' onClick= { this.show.bind(this)}>Open Column Chooser</ButtonComponent>
        <GridComponent dataSource={data} showColumnChooser={true} height={295} ref={g => this.grid = g}>
            <ColumnsDirective>
                    <ColumnDirective field='OrderID' headerText='Order ID' width='120' textAlign='Right'></ColumnDirective>
                    <ColumnDirective field='CustomerID' headerText='Customer ID' width='150' showInColumnChooser={false} >
                    </ColumnDirective>
                    <ColumnDirective field='Freight' width='100' format='C2' textAlign='Right'></ColumnDirective>
                    <ColumnDirective field='OrderDate' width='140' format='yMd' textAlign='Right'></ColumnDirective>
                    <ColumnDirective field='ShipCity' headerText='Ship City' width='150'></ColumnDirective>
                    <ColumnDirective field='ShipName' headerText='Ship Name' width='150' visible = {false} >
                    </ColumnDirective>
            </ColumnsDirective>
            <Inject services={[ColumnChooser]}></Inject>
        </GridComponent>
        </div>)
    }
};
ReactDOM.render(<App />, document.getElementById('grid'));

Column menu

The column menu has options to integrate features like sorting, grouping, filtering, column chooser, and autofit. It will show a menu with the integrated feature when users click on multiple icon of the column. To enable column menu, you need to define the showColumnMenu property as true.

To use the column menu, inject the ColumnMenu module in the grid.

The default items are displayed in following table.

Item Description
SortAscending Sort the current column in ascending order.
SortDescending Sort the current column in descending order.
Group Group the current column.
Ungroup Ungroup the current column.
AutoFit Auto fit the current column.
AutoFitAll Auto fit all columns.
ColumnChooser Choose the column visibility.
Filter Show the filter option as given in filterSettings.type
Source
Preview
index.tsx
import * as ReactDOM from 'react-dom';
import * as React from 'react';
import { GridComponent, ColumnsDirective, ColumnDirective, Group, Sort, ColumnMenu, Filter, Page, Inject, ExcelExport, Edit, PdfExport } from '@syncfusion/ej2-react-grids';
import { GroupSettingsModel, FilterSettingsModel  } from '@syncfusion/ej2-react-grids';
import { data } from './datasource';

class App extends React.Component<{}, {}> {

    public groupOptions: GroupSettingsModel = { showGroupedColumn: true };
    public filterSettings: FilterSettingsModel = { type: 'CheckBox' };

    render() {
        return (
            <div>
                <GridComponent id='gridcomp' dataSource={data} allowPaging={true}  allowGrouping={true} allowSorting={true} showColumnMenu={true} allowExcelExport={true}  allowPdfExport={true} allowFiltering={true} groupSettings={this.groupOptions} filterSettings={this.filterSettings}>
                    <ColumnsDirective>
                        <ColumnDirective field='OrderID' headerText='Order ID' width='140' textAlign='Right' isPrimaryKey={true}></ColumnDirective>
                        <ColumnDirective field='CustomerID' headerText='Customer Name'></ColumnDirective>
                        <ColumnDirective field='Freight' headerText='Freight' format='C2' textAlign='Right' editType='numericedit' />
                        <ColumnDirective field='ShipName' headerText='Ship Name' width='200'></ColumnDirective>
                    </ColumnsDirective>
                    <Inject services={[Sort, ColumnMenu, Filter, Page, ExcelExport, Edit, PdfExport]} />
                    </GridComponent>
            </div>
        );
    }
}
ReactDOM.render(<App />, document.getElementById('grid'));

You can disable column menu for a particular column by defining the columns.showColumnMenu as false. You can customize the default items by defining the columnMenuItems with required items.

Column menu events

During the resizing action, the grid component triggers the below two events.

  1. The columnMenuOpen event triggers before the column menu opens.
  2. The columnMenuClick event triggers when the user clicks the column menu of the grid.
Source
Preview
index.tsx
import * as ReactDOM from 'react-dom';
import * as React from 'react';
import { GridComponent, ColumnsDirective, ColumnDirective, Group, Sort, ColumnMenu, Filter, Page, Inject, ExcelExport, Edit, PdfExport } from '@syncfusion/ej2-react-grids';
import { GroupSettingsModel, FilterSettingsModel  } from '@syncfusion/ej2-react-grids';
import { data } from './datasource';

class App extends React.Component<{}, {}> {

    public groupOptions: GroupSettingsModel = { showGroupedColumn: true };
    public filterSettings: FilterSettingsModel = { type: 'CheckBox' };
    public columnMenuOpen(){
       alert('columnMenuOpen event is Triggered');
    }
    public columnMenuClick(){
       alert('columnMenuClick event is Triggered');
    }
    render() {
        return (
            <div>
                <GridComponent id='gridcomp' dataSource={data} allowPaging={true}  allowGrouping={true} allowSorting={true} showColumnMenu={true} allowExcelExport={true}  allowPdfExport={true} allowFiltering={true} groupSettings={this.groupOptions} filterSettings={this.filterSettings}
                columnMenuOpen= { this.columnMenuOpen.bind(this)} columnMenuClick= { this.columnMenuClick.bind(this)}>
                    <ColumnsDirective>
                        <ColumnDirective field='OrderID' headerText='Order ID' width='140' textAlign='Right' isPrimaryKey={true}></ColumnDirective>
                        <ColumnDirective field='CustomerID' headerText='Customer Name'></ColumnDirective>
                        <ColumnDirective field='Freight' headerText='Freight' format='C2' textAlign='Right' editType='numericedit' />
                        <ColumnDirective field='ShipName' headerText='Ship Name' width='200'></ColumnDirective>
                    </ColumnsDirective>
                    <Inject services={[Sort, ColumnMenu, Filter, Page, ExcelExport, Edit, PdfExport]} />
                    </GridComponent>
            </div>
        );
    }
}
ReactDOM.render(<App />, document.getElementById('grid'));

Custom Column Menu Item

Custom column menu items can be added by defining the columnMenuItems as collection of the columnMenuItemModel. Actions for this customized items can be defined in the columnMenuClick event.

Source
Preview
index.tsx
import * as ReactDOM from 'react-dom';
import * as React from 'react';
import { GridComponent, ColumnsDirective, ColumnDirective, Sort, ColumnMenu, Page, Inject } from '@syncfusion/ej2-react-grids';
import { ColumnMenuItemModel, SortSettingsModel } from '@syncfusion/ej2-react-grids';
import { data } from './datasource';
import { MenuEventArgs } from '@syncfusion/ej2-navigations';

class App extends React.Component<{}, {}> {

    public grid: GridComponent;
    public columnMenuItems: ColumnMenuItemModel[] =  [{text:'Clear Sorting', id:'gridclearsorting'}];
    public sortSettings: SortSettingsModel = { columns:[{direction: "Ascending", field: "OrderID"}] };

    columnMenuClick(args: MenuEventArgs){
        if(args.item.id === 'gridclearsorting'){
            this.grid.clearSorting();
        }
    }

    render() {
        return (
            <div>
                <GridComponent id='gridcomp' dataSource={data} allowPaging={true} allowSorting={true} showColumnMenu={true} sortSettings={this.sortSettings}
                ref={g=> this.grid = g} columnMenuItems={this.columnMenuItems} columnMenuClick={this.columnMenuClick.bind(this)}>
                    <ColumnsDirective>
                        <ColumnDirective field='OrderID' headerText='Order ID' width='140' textAlign='Right' isPrimaryKey={true}></ColumnDirective>
                        <ColumnDirective field='CustomerID' headerText='Customer Name'></ColumnDirective>
                        <ColumnDirective field='Freight' headerText='Freight' format='C2' textAlign='Right' editType='numericedit' />
                        <ColumnDirective field='ShipName' headerText='Ship Name' width='200'></ColumnDirective>
                    </ColumnsDirective>
                    <Inject services={[Sort, ColumnMenu, Page]} />
                    </GridComponent>
            </div>
        );
    }
}
ReactDOM.render(<App />, document.getElementById('grid'));

Customize menu items for particular columns

Sometimes, you have a scenario that to hide an item from column menu for particular columns. In that case, you need to define the columnMenuOpenEventArgs.hide as true in the columnMenuOpen event.

The following sample, Filter item was hidden in column menu when opens for the OrderID column.

Source
Preview
index.tsx
import * as ReactDOM from 'react-dom';
import * as React from 'react';
import { GridComponent, ColumnsDirective, ColumnDirective, ColumnMenu, Sort, Page, Filter, ColumnMenuOpenEventArgs, ColumnMenuItemModel, FilterSettingsModel, Inject } from '@syncfusion/ej2-react-grids';
import { data } from './datasource';

class App extends React.Component<{}, {}> {

    public filterOptions: FilterSettingsModel = {type: 'Menu'};

    columnMenuOpen (args: ColumnMenuOpenEventArgs) {
        for (let item of args.items) {
            if (item.text === 'Filter' && args.column.field === 'OrderID') {
                (item as ColumnMenuItemModel).hide = true;
            } else {
                (item as ColumnMenuItemModel).hide = false;
            }
        }
    }

    render() {
        return (
            <div>
                <GridComponent id='gridcomp' dataSource={data} allowPaging={true}  allowGrouping={true} showColumnMenu={true} allowFiltering={true} allowSorting={true} filterSettings={this.filterOptions} columnMenuOpen={this.columnMenuOpen.bind(this)}>
                    <ColumnsDirective>
                        <ColumnDirective field='OrderID' headerText='Order ID' width='140' textAlign='Right' isPrimaryKey={true}></ColumnDirective>
                        <ColumnDirective field='CustomerID' headerText='Customer Name'></ColumnDirective>
                        <ColumnDirective field='Freight' headerText='Freight' format='C2' textAlign='Right' editType='numericedit' />
                        <ColumnDirective field='ShipName' headerText='Ship Name' width='200'></ColumnDirective>
                    </ColumnsDirective>
                    <Inject services={[Sort, ColumnMenu, Filter, Page]} />
                    </GridComponent>
            </div>
        );
    }
}
ReactDOM.render(<App />, document.getElementById('grid'));

Column Spanning

Grid has option to span the adjacent cells. You need to define colSpan attribute to span the cells in QueryCellInfo event.

In the following demo, Employee Davolio doing analysis from 9.00 AM to 10.00 AM, so that cells have spanned.

Source
Preview
index.tsx
datasource.tsx
import * as ReactDOM from 'react-dom';
import * as React from 'react';
import { GridComponent, ColumnsDirective, ColumnDirective, Inject, QueryCellInfoEventArgs } from '@syncfusion/ej2-react-grids';
import { columnSpanData, ColumnSpanDataType } from './datasource';
import { SampleBase } from '../common/sample-base';

class ColumnSpanning extends React.Component<{}, {}> {
    public queryCellInfoEvent = (args: QueryCellInfoEventArgs) => {
        let data: ColumnSpanDataType = args.data as ColumnSpanDataType;
        switch (data.EmployeeID) {
            case 10001:
                if (args.column.field === '9:00' || args.column.field === '2:30' || args.column.field === '4:30') {
                    args.colSpan = 2;
                } else if (args.column.field === '11:00') {
                    args.colSpan = 3;
                }
                break;
            case 10002:
                if (args.column.field === '9:30' || args.column.field === '2:30' ||
                    args.column.field === '4:30') {
                    args.colSpan = 3;
                } else if (args.column.field === '11:00') {
                    args.colSpan = 4;
                }
                break;
            case 10003:
                if (args.column.field === '9:00' || args.column.field === '11:30') {
                    args.colSpan = 3;
                } else if (args.column.field === '10:30' || args.column.field === '3:30' ||
                    args.column.field === '4:30' || args.column.field === '2:30') {
                    args.colSpan = 2;
                }
                break;
            case 10004:
                if (args.column.field === '9:00') {
                    args.colSpan = 3;
                } else if (args.column.field === '11:00') {
                    args.colSpan = 4;
                } else if (args.column.field === '4:00' || args.column.field === '2:30') {
                    args.colSpan = 2;
                }
                break;
            case 10005:
                if (args.column.field === '9:00') {
                    args.colSpan = 4;
                } else if (args.column.field === '11:30') {
                    args.colSpan = 3;
                } else if (args.column.field === '3:30' || args.column.field === '4:30' || args.column.field === '2:30') {
                    args.colSpan = 2;
                }
                break;
            case 10006:
                if (args.column.field === '9:00' || args.column.field === '4:30' ||
                    args.column.field === '2:30' || args.column.field === '3:30') {
                    args.colSpan = 2;
                } else if (args.column.field === '10:00' || args.column.field === '11:30') {
                    args.colSpan = 3;
                }
                break;
            case 10007:
                if (args.column.field === '9:00' || args.column.field === '3:00' || args.column.field === '10:30') {
                    args.colSpan = 2;
                } else if (args.column.field === '11:30' || args.column.field === '4:00') {
                    args.colSpan = 3;
                }
                break;
            case 10008:
                if (args.column.field === '9:00' || args.column.field === '10:30' || args.column.field === '2:30') {
                    args.colSpan = 3;
                } else if (args.column.field === '4:00') {
                    args.colSpan = 2;
                }
                break;
            case 10009:
                if (args.column.field === '9:00' || args.column.field === '11:30') {
                    args.colSpan = 3;
                } else if (args.column.field === '4:30' || args.column.field === '2:30') {
                    args.colSpan = 2;
                }
                break;
            case 100010:
                if (args.column.field === '9:00' || args.column.field === '2:30' ||
                    args.column.field === '4:00' || args.column.field === '11:30') {
                    args.colSpan = 3;
                } else if (args.column.field === '10:30') {
                    args.colSpan = 2;
                }
                break;
        }
    };
    render() {
        return (
            <div className='control-pane'>
                <div className='control-section'>
                    <GridComponent dataSource={columnSpanData} queryCellInfo={this.queryCellInfoEvent.bind(this)} allowTextWrap={true} height='auto' width='auto' gridLines='Both' >
                        <ColumnsDirective>
                            <ColumnDirective field='EmployeeID' headerText='Employee ID' width='150' isPrimaryKey={true} textAlign='Right'></ColumnDirective>
                            <ColumnDirective field='EmployeeName' headerText='Employee Name' width='200' ></ColumnDirective>
                            <ColumnDirective field='9:00' headerText='9:00 AM' width='120'></ColumnDirective>
                            <ColumnDirective field='9:30' headerText='9:30 AM' width='120'></ColumnDirective>
                            <ColumnDirective field='10:00' headerText='10:00 AM' width='120'></ColumnDirective>
                            <ColumnDirective field='10:30' headerText='10:30 AM' width='120'></ColumnDirective>
                            <ColumnDirective field='11:00' headerText='11:00 AM' width='120'></ColumnDirective>
                            <ColumnDirective field='11:30' headerText='11:30 AM' width='120'></ColumnDirective>
                            <ColumnDirective field='12:00' headerText='12:00 PM' width='120'></ColumnDirective>
                            <ColumnDirective field='12:30' headerText='12:30 PM' width='120'></ColumnDirective>
                            <ColumnDirective field='2:30' headerText='2:30 PM' width='120'></ColumnDirective>
                            <ColumnDirective field='3:00' headerText='3:00 PM' width='120'></ColumnDirective>
                            <ColumnDirective field='3:30' headerText='3:30 PM' width='120'></ColumnDirective>
                            <ColumnDirective field='4:00' headerText='4:00 PM' width='120'></ColumnDirective>
                            <ColumnDirective field='4:30' headerText='4:30 PM' width='120'></ColumnDirective>
                            <ColumnDirective field='5:00' headerText='5:00 PM' width='120'></ColumnDirective>
                        </ColumnsDirective>
                    </GridComponent>
                </div>
            </div>
        )
    }
}
ReactDOM.render(<ColumnSpanning />, document.getElementById('grid'));
export interface ColumnSpanDataType {
    EmployeeID: number;
    EmployeeName: string;
    '9:00': string;
    '9:30': string;
    '10:00': string;
    '10:30': string;
    '11:00': string;
    '11:30': string;
    '12:00': string;
    '12:30': string;
    '1:00': string;
    '1:30': string;
    '2:00': string;
    '2:30': string;
    '3:00': string;
    '3:30': string;
    '4:00': string;
    '4:30': string;
    '5:00': string;
}

export let columnSpanData: ColumnSpanDataType[] = [
    {
        EmployeeID: 10001,
        EmployeeName: 'Davolio',
        '9:00': 'Analysis Tasks',
        '9:30': 'Analysis Tasks',
        '10:00': 'Team Meeting',
        '10:30': 'Testing',
        '11:00': 'Development',
        '11:30': 'Development',
        '12:00': 'Development',
        '12:30': 'Support',
        '1:00': 'Lunch Break',
        '1:30': 'Lunch Break',
        '2:00': 'Lunch Break',
        '2:30': 'Testing',
        '3:00': 'Testing',
        '3:30': 'Development',
        '4:00': 'Conference',
        '4:30': 'Team Meeting',
        '5:00': 'Team Meeting'
    },
    {
        EmployeeID: 10002,
        EmployeeName: 'Buchanan',
        '9:00': 'Task Assign',
        '9:30': 'Support',
        '10:00': 'Support',
        '10:30': 'Support',
        '11:00': 'Testing',
        '11:30': 'Testing',
        '12:00': 'Testing',
        '12:30': 'Testing',
        '1:00': 'Lunch Break',
        '1:30': 'Lunch Break',
        '2:00': 'Lunch Break',
        '2:30': 'Development',
        '3:00': 'Development',
        '3:30': 'Check Mail',
        '4:00': 'Check Mail',
        '4:30': 'Team Meeting',
        '5:00': 'Team Meeting'
    },
    {
        EmployeeID: 10003,
        EmployeeName: 'Fuller',
        '9:00': 'Check Mail',
        '9:30': 'Check Mail',
        '10:00': 'Check Mail',
        '10:30': 'Analysis Tasks',
        '11:00': 'Analysis Tasks',
        '11:30': 'Support',
        '12:00': 'Support',
        '12:30': 'Support',
        '1:00': 'Lunch Break',
        '1:30': 'Lunch Break',
        '2:00': 'Lunch Break',
        '2:30': 'Development',
        '3:00': 'Development',
        '3:30': 'Team Meeting',
        '4:00': 'Team Meeting',
        '4:30': 'Development',
        '5:00': 'Development'
    },
    {
        EmployeeID: 10004,
        EmployeeName: 'Leverling',
        '9:00': 'Testing',
        '9:30': 'Check Mail',
        '10:00': 'Check Mail',
        '10:30': 'Support',
        '11:00': 'Testing',
        '11:30': 'Testing',
        '12:00': 'Testing',
        '12:30': 'Testing',
        '1:00': 'Lunch Break',
        '1:30': 'Lunch Break',
        '2:00': 'Lunch Break',
        '2:30': 'Development',
        '3:00': 'Development',
        '3:30': 'Check Mail',
        '4:00': 'Conference',
        '4:30': 'Conference',
        '5:00': 'Team Meeting'
    },
    {
        EmployeeID: 10005,
        EmployeeName: 'Peacock',
        '9:00': 'Task Assign',
        '9:30': 'Task Assign',
        '10:00': 'Task Assign',
        '10:30': 'Task Assign',
        '11:00': 'Check Mail',
        '11:30': 'Support',
        '12:00': 'Support',
        '12:30': 'Support',
        '1:00': 'Lunch Break',
        '1:30': 'Lunch Break',
        '2:00': 'Lunch Break',
        '2:30': 'Development',
        '3:00': 'Development',
        '3:30': 'Team Meeting',
        '4:00': 'Team Meeting',
        '4:30': 'Testing',
        '5:00': 'Testing'
    },
    {
        EmployeeID: 10006,
        EmployeeName: 'Janet',
        '9:00': 'Testing',
        '9:30': 'Testing',
        '10:00': 'Support',
        '10:30': 'Support',
        '11:00': 'Support',
        '11:30': 'Team Meeting',
        '12:00': 'Team Meeting',
        '12:30': 'Team Meeting',
        '1:00': 'Lunch Break',
        '1:30': 'Lunch Break',
        '2:00': 'Lunch Break',
        '2:30': 'Development',
        '3:00': 'Development',
        '3:30': 'Team Meeting',
        '4:00': 'Team Meeting',
        '4:30': 'Development',
        '5:00': 'Development'
    },
    {
        EmployeeID: 10007,
        EmployeeName: 'Suyama',
        '9:00': 'Analysis Tasks',
        '9:30': 'Analysis Tasks',
        '10:00': 'Testing',
        '10:30': 'Development',
        '11:00': 'Development',
        '11:30': 'Testing',
        '12:00': 'Testing',
        '12:30': 'Testing',
        '1:00': 'Lunch Break',
        '1:30': 'Lunch Break',
        '2:00': 'Lunch Break',
        '2:30': 'Support',
        '3:00': 'Build',
        '3:30': 'Build',
        '4:00': 'Check Mail',
        '4:30': 'Check Mail',
        '5:00': 'Check Mail'
    },
    {
        EmployeeID: 10008,
        EmployeeName: 'Robert',
        '9:00': 'Task Assign',
        '9:30': 'Task Assign',
        '10:00': 'Task Assign',
        '10:30': 'Development',
        '11:00': 'Development',
        '11:30': 'Development',
        '12:00': 'Testing',
        '12:30': 'Support',
        '1:00': 'Lunch Break',
        '1:30': 'Lunch Break',
        '2:00': 'Lunch Break',
        '2:30': 'Check Mail',
        '3:00': 'Check Mail',
        '3:30': 'Check Mail',
        '4:00': 'Team Meeting',
        '4:30': 'Team Meeting',
        '5:00': 'Build'
    },
    {
        EmployeeID: 10009,
        EmployeeName: 'Andrew',
        '9:00': 'Check Mail',
        '9:30': 'Team Meeting',
        '10:00': 'Team Meeting',
        '10:30': 'Support',
        '11:00': 'Testing',
        '11:30': 'Development',
        '12:00': 'Development',
        '12:30': 'Development',
        '1:00': 'Lunch Break',
        '1:30': 'Lunch Break',
        '2:00': 'Lunch Break',
        '2:30': 'Check Mail',
        '3:00': 'Check Mail',
        '3:30': 'Check Mail',
        '4:00': 'Team Meeting',
        '4:30': 'Development',
        '5:00': 'Development'
    },
    {
        EmployeeID: 10010,

        EmployeeName: 'Michael',
        '9:00': 'Task Assign',
        '9:30': 'Task Assign',
        '10:00': 'Task Assign',
        '10:30': 'Analysis Tasks',
        '11:00': 'Analysis Tasks',
        '11:30': 'Development',
        '12:00': 'Development',
        '12:30': 'Development',
        '1:00': 'Lunch Break',
        '1:30': 'Lunch Break',
        '2:00': 'Lunch Break',
        '2:30': 'Testing',
        '3:00': 'Testing',
        '3:30': 'Testing',
        '4:00': 'Build',
        '4:30': 'Build',
        '5:00': 'Build'
    }
];

Responsive Columns

You can toggle column visibility based on media queries which are defined at the hideAtMedia. The hideAtMedia accepts valid Media Queries. In the below sample, for OrderID column, hideAtMedia property value is set as (min-width: 700px) so that OrderID column will gets hidden when the browser screen width is lessthan 700px.

Source
Preview
index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GridComponent, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-grids';
import { data } from '../datasource.ts';

class App extends React.Component<{}, {}>{
    public data: Object[] = data;
    render() {
        return <GridComponent dataSource={this.data} height={315}>
                <ColumnsDirective>
                    <ColumnDirective field='OrderID' headerText='Order ID' width='120' textAlign="Right"
                    hideAtMedia = '(min-width:700px)'> </ColumnDirective>
                    //  column visibility hide when browser screen width lessthan 700px;

                    <ColumnDirective field='CustomerID' headerText='Customer ID' width='150'
                    hideAtMedia = '(max-width:500px)'> </ColumnDirective>
                    // column Visibility show when browser screen width  500px or less;

                    <ColumnDirective field='ShipCity' headerText='Ship City' width='150'
                    hideAtMedia = '(min-width:500px)'> </ColumnDirective>
                   //  column visibility hide when browser screen width lessthan 700px;

                   <ColumnDirective field='ShipName' headerText='Ship Name' width='150'></ColumnDirective>
                //  it is always shown;
                </ColumnsDirective>
               </GridComponent>
    }
}
ReactDOM.render(<App />, document.getElementById('grid'));

Controlling Grid Actions

You can enable or disable grid action for a particular column by setting the allowFiltering, allowGrouping, allowSorting properties, allowEditing properties and allowReordering properties.

Source
Preview
index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GridComponent, Inject, ColumnsDirective, ColumnDirective, Sort, Filter, Group, Edit, Reorder } from '@syncfusion/ej2-react-grids';
import { data } from '../datasource.ts';

class App extends React.Component<{}, {}>{
    public data: Object[] = data;
    public editOptions: EditSettingsModel = { allowEditing: true, allowAdding: true, allowDeleting: true };
    render() {
        return <GridComponent dataSource={data} allowSorting={true} editSettings={this.editOptions} allowFiltering={true} allowReordering={true} allowGrouping={true} height={230}>
                <ColumnsDirective>
                 <ColumnDirective field='OrderID' width='100' textAlign="Right" allowGrouping={false}></ColumnDirective>
                 <ColumnDirective field='CustomerID' width='100'></ColumnDirective>
                 <ColumnDirective field='Freight' width='100' format="C2" textAlign="Right" allowEditing={false}allowReordering={false} allowFiltering={false}></ColumnDirective>
                 <ColumnDirective field='OrderDate' width='140' format="yMd" textAlign="Right" allowSorting={false}></ColumnDirective>
                </ColumnsDirective>
                <Inject services={[Sort, Filter, Group]} />
               </GridComponent>
    }
}
ReactDOM.render(<App />, document.getElementById('grid'));

Show/Hide Columns by External Button

You can show or hide the grid columns dynamically through external buttons by invoking the showColumns/hideColumns methods.

Source
Preview
index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { ButtonComponent } from '@syncfusion/ej2-react-buttons';
import { Grid, GridComponent, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-grids';
import { data } from '../datasource.ts';

class App extends React.Component<{}, {}>{
    public show() {
        this.grid.showColumns(['Customer ID', 'Freight']); //show by HeaderText
    }

    public hide(){
        this.grid.hideColumns(['Customer ID', 'Freight']); //hide by HeaderText
    }
    private grid: Grid;
    render() {
        return (<div>
        <ButtonComponent value='Show' cssClass= 'e-flat' onClick= { this.show.bind(this)}>Show</ButtonComponent>
        <ButtonComponent value='Hide' cssClass= 'e-flat' onClick= { this.hide.bind(this)}>Hide</ButtonComponent>
        <GridComponent dataSource={data} height={295} ref={g => this.grid = g}>
            <ColumnsDirective>
                <ColumnDirective field='OrderID' headerText='Order ID' width='100' textAlign="Right"></ColumnDirective>
                <ColumnDirective field='CustomerID' headerText='Customer ID' width='100'></ColumnDirective>
                <ColumnDirective field='EmployeeID' headerText='Employee ID' width='100' textAlign="Right"></ColumnDirective>
                <ColumnDirective field='Freight' headerText='Freight' width='100' format="C2" textAlign="Right"></ColumnDirective>
                <ColumnDirective field='ShipCountry' headerText='Ship Country' width='100'></ColumnDirective>
            </ColumnsDirective>
        </GridComponent>
        </div>)
    }
};
ReactDOM.render(<App />, document.getElementById('grid'));

Complex Data Binding

You can achieve complex data binding in the grid by using the dot(.) operator in the column.field.

Source
Preview
index.tsx
datasource.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { Grid, GridComponent, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-grids';
import { complexData } from './datasource';

class App extends React.Component<{}, {}>{
    private grid: Grid;
    render() {
        return (<div>
        <GridComponent dataSource={complexData} height={315 }>
            <ColumnsDirective>
                <ColumnDirective field='EmployeeID' headerText='Employee ID' width='120' textAlign="Right"></ColumnDirective>
                <ColumnDirective field='Name.FirstName' headerText='First Name' width='120'></ColumnDirective>
                <ColumnDirective field='Name.LastName' headerText='Last Name' width='120'></ColumnDirective>
                <ColumnDirective field='Title' headerText='Title' width='150'></ColumnDirective>
            </ColumnsDirective>
        </GridComponent>
        </div>)
    }
};
ReactDOM.render(<App />, document.getElementById('grid'));
export let complexData: Object[] = [{
    'EmployeeID': 1,
    'Name': {
    'LastName': 'Davolio',
    'FirstName': 'Nancy'},
    'Names': [{
        'LastName' : 'Davolio',
        'FirstName': 'Nancy'}],
    'Title': 'Sales Representative',
    'TitleOfCourtesy': 'Ms.',
    'BirthDate': new Date(-664743600000),
    'HireDate': new Date(704692800000),
    'Address': '507 - 20th Ave. E.\r\nApt. 2A',
    'City': 'Seattle',
    'Region': 'WA',
    'PostalCode': '98122',
    'Country': 'USA',
    'HomePhone': '(206) 555-9857',
    'Extension': '5467',
    'Photo': { 'Length': 21626 },

    'Notes': 'Education includes a BA in psychology from Colorado State University in 1970.  She also completed\
    \'The Art of the Cold Call.\'  Nancy is a member of Toastmasters International.',
    'ReportsTo': 2,
    'PhotoPath': 'http://accweb/emmployees/davolio.bmp'
},
{
    'EmployeeID': 2,
    'Name':{
    'LastName': 'Fuller',
    'FirstName': 'Andrew'},
    'Names': [{
    'LastName': 'Fuller',
    'FirstName': 'Andrew'}],
    'Title': 'Vice President, Sales',
    'TitleOfCourtesy': 'Dr.',
    'BirthDate': new Date(-563828400000),
    'HireDate': new Date(713764800000),
    'Address': '908 W. Capital Way',
    'City': 'Tacoma',
    'Region': 'WA',
    'PostalCode': '98401',
    'Country': 'USA',
    'HomePhone': '(206) 555-9482',
    'Extension': '3457',
    'Photo': { 'Length': 21626 },

    'Notes': 'Andrew received his BTS commercial in 1974 and a Ph.D. in international marketing from the University of \
    Dallas in 1981.  He is fluent in French and Italian and reads German.  He joined the company as a sales representative, \
    was promoted to sales manager in January 1992 and to vice president of sales in March 1993.  Andrew is a member of the \
    Sales Management Roundtable, the Seattle Chamber of Commerce, and the Pacific Rim Importers Association.',
    'ReportsTo': 0,
    'PhotoPath': 'http://accweb/emmployees/fuller.bmp'
},
{
    'EmployeeID': 3,
    'Name':{
    'LastName': 'Leverling',
    'FirstName': 'Janet'},
    'Names': [{
        'LastName': 'Leverling',
        'FirstName': 'Janet'}],
    'Title': 'Sales Representative',
    'TitleOfCourtesy': 'Ms.',
    'BirthDate': new Date(-200088000000),
    'HireDate': new Date(702104400000),
    'Address': '722 Moss Bay Blvd.',
    'City': 'Kirkland',
    'Region': 'WA',
    'PostalCode': '98033',
    'Country': 'USA',
    'HomePhone': '(206) 555-3412',
    'Extension': '3355',
    'Photo': { 'Length': 21722 },

    'Notes': 'Janet has a BS degree in chemistry from Boston College (1984). \
     She has also completed a certificate program in food retailing management.\
     Janet was hired as a sales associate in 1991 and promoted to sales representative in February 1992.',
    'ReportsTo': 2,
    'PhotoPath': 'http://accweb/emmployees/leverling.bmp'
},
{
    'EmployeeID': 4,
    'Name':{
    'LastName': 'Peacock',
    'FirstName': 'Margaret'},
    'Names': [{
        'LastName': 'Peacock',
        'FirstName': 'Margaret'}],
    'Title': 'Sales Representative',
    'TitleOfCourtesy': 'Mrs.',
    'BirthDate': new Date(-1018814400000),
    'HireDate': new Date(736401600000),
    'Address': '4110 Old Redmond Rd.',
    'City': 'Redmond',
    'Region': 'WA',
    'PostalCode': '98052',
    'Country': 'USA',
    'HomePhone': '(206) 555-8122',
    'Extension': '5176',
    'Photo': { 'Length': 21626 },

    'Notes': 'Margaret holds a BA in English literature from Concordia College (1958) and an MA from the American \
    Institute of Culinary Arts (1966).  She was assigned to the London office temporarily from July through November 1992.',
    'ReportsTo': 2,
    'PhotoPath': 'http://accweb/emmployees/peacock.bmp'
},
{
    'EmployeeID': 5,
    'Name':{
    'LastName': 'Buchanan',
    'FirstName': 'Steven'},
    'Names': [{
        'LastName': 'Buchanan',
        'FirstName': 'Steven'}],
    'Title': 'Sales Manager',
    'TitleOfCourtesy': 'Mr.',
    'BirthDate': new Date(-468010800000),
    'HireDate': new Date(750830400000),
    'Address': '14 Garrett Hill',
    'City': 'London',
    'Region': null,
    'PostalCode': 'SW1 8JR',
    'Country': 'UK',
    'HomePhone': '(71) 555-4848',
    'Extension': '3453',
    'Photo': { 'Length': 21626 },

    'Notes': 'Steven Buchanan graduated from St. Andrews University, Scotland, with a BSC degree in 1976.  Upon joining the company as \
    a sales representative in 1992, he spent 6 months in an orientation program at the Seattle office and then returned to his permanent \
    post in London.  He was promoted to sales manager in March 1993.  Mr. Buchanan has completed the courses \'Successful \
    Telemarketing\' and \'International Sales Management.\'  He is fluent in French.',
    'ReportsTo': 2,
    'PhotoPath': 'http://accweb/emmployees/buchanan.bmp'
},
{
    'EmployeeID': 6,
    'Name':{
    'LastName': 'Suyama',
    'FirstName': 'Michael'},
    'Title': 'Sales Representative',
    'TitleOfCourtesy': 'Mr.',
    'BirthDate': new Date(-205185600000),
    'HireDate': new Date(750830400000),
    'Address': 'Coventry House\r\nMiner Rd.',
    'City': 'London',
    'Region': null,
    'PostalCode': 'EC2 7JR',
    'Country': 'UK',
    'HomePhone': '(71) 555-7773',
    'Extension': '428',
    'Photo': { 'Length': 21626 },

    'Notes': 'Michael is a graduate of Sussex University (MA, economics, 1983) and the University of California at Los Angeles \
    (MBA, marketing, 1986).  He has also taken the courses \'Multi-Cultural Selling\' and \'Time Management for the Sales Professional.\'  \
    He is fluent in Japanese and can read and write French, Portuguese, and Spanish.',
    'ReportsTo': 5,
    'PhotoPath': 'http://accweb/emmployees/davolio.bmp'
},
{
    'EmployeeID': 7,
    'Name':{
    'LastName': 'King',
    'FirstName': 'Robert'},
    'Title': 'Sales Representative',
    'TitleOfCourtesy': 'Mr.',
    'BirthDate': new Date(-302731200000),
    'HireDate': new Date(757486800000),
    'Address': 'Edgeham Hollow\r\nWinchester Way',
    'City': 'London',
    'Region': null,
    'PostalCode': 'RG1 9SP',
    'Country': 'UK',
    'HomePhone': '(71) 555-5598',
    'Extension': '465',
    'Photo': { 'Length': 21626 },

    'Notes': 'Robert King served in the Peace Corps and traveled extensively before completing his degree in English at the \
    University of Michigan in 1992, the year he joined the company.  After completing a course entitled \'Selling in Europe,\' \
    he was transferred to the London office in March 1993.',
    'ReportsTo': 5,
    'PhotoPath': 'http://accweb/emmployees/davolio.bmp'
},
{
    'EmployeeID': 8,
    'Name': {
    'LastName': 'Callahan',
    'FirstName': 'Laura'},
    'Title': 'Inside Sales Coordinator',
    'TitleOfCourtesy': 'Ms.',
    'BirthDate': new Date(-377982000000),
    'HireDate': new Date(762843600000),
    'Address': '4726 - 11th Ave. N.E.',
    'City': 'Seattle',
    'Region': 'WA',
    'PostalCode': '98105',
    'Country': 'USA',
    'HomePhone': '(206) 555-1189',
    'Extension': '2344',
    'Photo': { 'Length': 21626 },

    'Notes': 'Laura received a BA in psychology from the University of Washington.  She has also completed a course in business \
    French.  She reads and writes French.',
    'ReportsTo': 2,
    'PhotoPath': 'http://accweb/emmployees/davolio.bmp'
},
{
    'EmployeeID': 9,
    'Name': {
    'LastName': 'Dodsworth',
    'FirstName': 'Anne'},
    'Title': 'Sales Representative',
    'TitleOfCourtesy': 'Ms.',
    'BirthDate': new Date(-123966000000),
    'HireDate': new Date(784875600000),
    'Address': '7 Houndstooth Rd.',
    'City': 'London',
    'Region': null,
    'PostalCode': 'WG2 7LT',
    'Country': 'UK',
    'HomePhone': '(71) 555-4444',
    'Extension': '452',
    'Photo': { 'Length': 21626 },

    'Notes': 'Anne has a BA degree in English from St. Lawrence College.  She is fluent in French and German.',
    'ReportsTo': 5,
    'PhotoPath': 'http://accweb/emmployees/davolio.bmp'
}];

ValueAccessor

The valueAccessor is used to access/manipulate the value of display data. You can achieve custom value formatting by using valueAccessor.

Source
Preview
index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { Grid, GridComponent, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-grids';
import { data } from '../datasource.ts';

class App extends React.Component<{}, {}>{

    public currencyFormatter(field: string, data: Object, column: Object){
        return '€' + data['Freight'];
    }

    public valueAccess(field: string, data: Object, column: Object){
        return data[field] + '-' + data['ShipRegion'];
    }

    render() {
        return (<div>
        <GridComponent dataSource={data} height={315} >
            <ColumnsDirective>
                <ColumnDirective field='OrderID' headerText='Order ID' width='100' textAlign="Right"></ColumnDirective>
                <ColumnDirective field='CustomerID' headerText='Customer ID' width='100'></ColumnDirective>
                <ColumnDirective field='EmployeeID' headerText='Employee ID' width='100' textAlign="Right"></ColumnDirective>
                <ColumnDirective field='Freight' headerText='Freight' width='80' textAlign="Right" valueAccessor={this.currencyFormatter.bind(this)}></ColumnDirective>
                <ColumnDirective field='ShipCountry' headerText='Ship Country' width='100' valueAccessor={this.valueAccess.bind(this)}></ColumnDirective>
            </ColumnsDirective>
        </GridComponent>
        </div>)
    }
};
ReactDOM.render(<App />, document.getElementById('grid'));

Display Array type Columns

You can bind an Array of Objects in a column by using valueAccessor property. In this example, The Name field has an array of two objects FirstName and LastName. These two objects are joined and bind to a column using valueAccessor.

Source
Preview
index.tsx
datasource.tsx
index.css
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { Grid, GridComponent, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-grids';
import { stringData } from './datasource';

class App extends React.Component<{}, {}>{

    public valueAccess(field: string, data: Object, column: Object){
        return data[field].map(function(s){return s.LastName || s.FirstName}).join(' ');
    }

    render() {
        return (<div>
        <GridComponent dataSource={stringData} height={315} >
            <ColumnsDirective>
                <ColumnDirective field='EmployeeID' headerText='Employee ID' width='120' textAlign="Right"></ColumnDirective>
                <ColumnDirective field='Name' headerText='Full Name' width='120' valueAccessor={this.valueAccess.bind(this)}></ColumnDirective>
                <ColumnDirective field='Title' headerText='Title' width='160' textAlign="Right"></ColumnDirective>
            </ColumnsDirective>
        </GridComponent>
        </div>)
    }
};
ReactDOM.render(<App />, document.getElementById('grid'));
export let stringData: Object[] = [{
    'EmployeeID': 1,
    'Name': [{
    'FirstName': 'Davolio'},
    {'LastName': 'Nancy'}],
    'Title': 'Sales Representative',
    'TitleOfCourtesy': 'Ms.',
    'BirthDate': new Date(-664743600000),
    'HireDate': new Date(704692800000),
    'Address': '507 - 20th Ave. E.\r\nApt. 2A',
    'City': 'Seattle',
    'Region': 'WA',
    'PostalCode': '98122',
    'Country': 'USA',
    'HomePhone': '(206) 555-9857',
    'Extension': '5467',
    'Photo': { 'Length': 21626 },

    'Notes': 'Education includes a BA in psychology from Colorado State University in 1970.  She also completed\
    \'The Art of the Cold Call.\'  Nancy is a member of Toastmasters International.',
    'ReportsTo': 2,
    'PhotoPath': 'http://accweb/emmployees/davolio.bmp'
},
{
    'EmployeeID': 2,
    'Name':[{
    'FirstName': 'Fuller'},
    {'LastName': 'Andrew'}],
    'Title': 'Vice President, Sales',
    'TitleOfCourtesy': 'Dr.',
    'BirthDate': new Date(-563828400000),
    'HireDate': new Date(713764800000),
    'Address': '908 W. Capital Way',
    'City': 'Tacoma',
    'Region': 'WA',
    'PostalCode': '98401',
    'Country': 'USA',
    'HomePhone': '(206) 555-9482',
    'Extension': '3457',
    'Photo': { 'Length': 21626 },

    'Notes': 'Andrew received his BTS commercial in 1974 and a Ph.D. in international marketing from the University of \
    Dallas in 1981.  He is fluent in French and Italian and reads German.  He joined the company as a sales representative, \
    was promoted to sales manager in January 1992 and to vice president of sales in March 1993.  Andrew is a member of the \
    Sales Management Roundtable, the Seattle Chamber of Commerce, and the Pacific Rim Importers Association.',
    'ReportsTo': 0,
    'PhotoPath': 'http://accweb/emmployees/fuller.bmp'
},
{
    'EmployeeID': 3,
    'Name':[{
    'FirstName': 'Leverling'},
    {'LastName': 'Janet'}],
    'Title': 'Sales Representative',
    'TitleOfCourtesy': 'Ms.',
    'BirthDate': new Date(-200088000000),
    'HireDate': new Date(702104400000),
    'Address': '722 Moss Bay Blvd.',
    'City': 'Kirkland',
    'Region': 'WA',
    'PostalCode': '98033',
    'Country': 'USA',
    'HomePhone': '(206) 555-3412',
    'Extension': '3355',
    'Photo': { 'Length': 21722 },

    'Notes': 'Janet has a BS degree in chemistry from Boston College (1984). \
     She has also completed a certificate program in food retailing management.\
     Janet was hired as a sales associate in 1991 and promoted to sales representative in February 1992.',
    'ReportsTo': 2,
    'PhotoPath': 'http://accweb/emmployees/leverling.bmp'
},
{
    'EmployeeID': 4,
    'Name':[{
    'FirstName': 'Peacock'},
    {'LastName': 'Margaret'}],
    'Title': 'Sales Representative',
    'TitleOfCourtesy': 'Mrs.',
    'BirthDate': new Date(-1018814400000),
    'HireDate': new Date(736401600000),
    'Address': '4110 Old Redmond Rd.',
    'City': 'Redmond',
    'Region': 'WA',
    'PostalCode': '98052',
    'Country': 'USA',
    'HomePhone': '(206) 555-8122',
    'Extension': '5176',
    'Photo': { 'Length': 21626 },

    'Notes': 'Margaret holds a BA in English literature from Concordia College (1958) and an MA from the American \
    Institute of Culinary Arts (1966).  She was assigned to the London office temporarily from July through November 1992.',
    'ReportsTo': 2,
    'PhotoPath': 'http://accweb/emmployees/peacock.bmp'
},
{
    'EmployeeID': 5,
    'Name':[{
    'FirstName': 'Buchanan'},
    {'LastName': 'Steven'}],
    'Title': 'Sales Manager',
    'TitleOfCourtesy': 'Mr.',
    'BirthDate': new Date(-468010800000),
    'HireDate': new Date(750830400000),
    'Address': '14 Garrett Hill',
    'City': 'London',
    'Region': null,
    'PostalCode': 'SW1 8JR',
    'Country': 'UK',
    'HomePhone': '(71) 555-4848',
    'Extension': '3453',
    'Photo': { 'Length': 21626 },

    'Notes': 'Steven Buchanan graduated from St. Andrews University, Scotland, with a BSC degree in 1976.  Upon joining the company as \
    a sales representative in 1992, he spent 6 months in an orientation program at the Seattle office and then returned to his permanent \
    post in London.  He was promoted to sales manager in March 1993.  Mr. Buchanan has completed the courses \'Successful \
    Telemarketing\' and \'International Sales Management.\'  He is fluent in French.',
    'ReportsTo': 2,
    'PhotoPath': 'http://accweb/emmployees/buchanan.bmp'
},
{
    'EmployeeID': 6,
    'Name':[{
    'FirstName': 'Suyama'},
    {'LastName': 'Michael'}],
    'Title': 'Sales Representative',
    'TitleOfCourtesy': 'Mr.',
    'BirthDate': new Date(-205185600000),
    'HireDate': new Date(750830400000),
    'Address': 'Coventry House\r\nMiner Rd.',
    'City': 'London',
    'Region': null,
    'PostalCode': 'EC2 7JR',
    'Country': 'UK',
    'HomePhone': '(71) 555-7773',
    'Extension': '428',
    'Photo': { 'Length': 21626 },

    'Notes': 'Michael is a graduate of Sussex University (MA, economics, 1983) and the University of California at Los Angeles \
    (MBA, marketing, 1986).  He has also taken the courses \'Multi-Cultural Selling\' and \'Time Management for the Sales Professional.\'  \
    He is fluent in Japanese and can read and write French, Portuguese, and Spanish.',
    'ReportsTo': 5,
    'PhotoPath': 'http://accweb/emmployees/davolio.bmp'
},
{
    'EmployeeID': 7,
    'Name':[{
    'FirstName': 'King'},
    {'LastName': 'Robert'}],
    'Title': 'Sales Representative',
    'TitleOfCourtesy': 'Mr.',
    'BirthDate': new Date(-302731200000),
    'HireDate': new Date(757486800000),
    'Address': 'Edgeham Hollow\r\nWinchester Way',
    'City': 'London',
    'Region': null,
    'PostalCode': 'RG1 9SP',
    'Country': 'UK',
    'HomePhone': '(71) 555-5598',
    'Extension': '465',
    'Photo': { 'Length': 21626 },

    'Notes': 'Robert King served in the Peace Corps and traveled extensively before completing his degree in English at the \
    University of Michigan in 1992, the year he joined the company.  After completing a course entitled \'Selling in Europe,\' \
    he was transferred to the London office in March 1993.',
    'ReportsTo': 5,
    'PhotoPath': 'http://accweb/emmployees/davolio.bmp'
},
{
    'EmployeeID': 8,
    'Name':[{
    'FirstName': 'Callahan'},
    {'LastName': 'Laura'}],
    'Title': 'Inside Sales Coordinator',
    'TitleOfCourtesy': 'Ms.',
    'BirthDate': new Date(-377982000000),
    'HireDate': new Date(762843600000),
    'Address': '4726 - 11th Ave. N.E.',
    'City': 'Seattle',
    'Region': 'WA',
    'PostalCode': '98105',
    'Country': 'USA',
    'HomePhone': '(206) 555-1189',
    'Extension': '2344',
    'Photo': { 'Length': 21626 },

    'Notes': 'Laura received a BA in psychology from the University of Washington.  She has also completed a course in business \
    French.  She reads and writes French.',
    'ReportsTo': 2,
    'PhotoPath': 'http://accweb/emmployees/davolio.bmp'
},
{
    'EmployeeID': 9,
    'Name': [{
    'FirstName': 'Dodsworth'},
    {'LastName': 'Anne'}],
    'Title': 'Sales Representative',
    'TitleOfCourtesy': 'Ms.',
    'BirthDate': new Date(-123966000000),
    'HireDate': new Date(784875600000),
    'Address': '7 Houndstooth Rd.',
    'City': 'London',
    'Region': null,
    'PostalCode': 'WG2 7LT',
    'Country': 'UK',
    'HomePhone': '(71) 555-4444',
    'Extension': '452',
    'Photo': { 'Length': 21626 },

    'Notes': 'Anne has a BA degree in English from St. Lawrence College.  She is fluent in French and German.',
    'ReportsTo': 5,
    'PhotoPath': 'http://accweb/emmployees/davolio.bmp'
}];
.orientationcss .e-headercelldiv {
  transform: rotate(90deg);
}

Expression Column

You can achieve the expression column by using valueAccessor property.

Source
Preview
index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GridComponent, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-grids';
import { foodInformation } from '../datasource.ts';

class App extends React.Component<{}, {}>{
    public totalCalories (field: string, data: { Protein: number, Fat: number, Carbohydrate: number }, column: Object): number {
        return data.Protein * 4 + data.Fat * 4 + data.Carbohydrate * 9;
    };
    render() {
        return <GridComponent dataSource={foodInformation} height={315}>
                <ColumnsDirective>
                    <ColumnDirective field='FoodName' width='100' ></ColumnDirective>
                    <ColumnDirective field='Protein' width='90' textAlign="Right" ></ColumnDirective>
                    <ColumnDirective field='Fat' width='90' textAlign="Right"></ColumnDirective>
                    <ColumnDirective field='Carbohydrate' width='100' textAlign="Right"></ColumnDirective>
                    <ColumnDirective headerText='Calories In Take' width='140'  textAlign="Right" valueAccessor= {this.totalCalories.bind(this)}></ColumnDirective>
                </ColumnsDirective>
        </GridComponent>
    }
};
ReactDOM.render(<App />, document.getElementById('grid'));

Foreign Key Column

Foreign key column can be enabled by using column.dataSource, column.foreignKeyField and column.foreignKeyValue properties.

In the following example, Employee Name is a foreign column which shows FirstName column from foreign data.

Source
Preview
index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GridComponent, ColumnsDirective, ColumnDirective, ForeignKey, Inject } from '@syncfusion/ej2-react-grids';
import { data, employeeData } from '../datasource.ts';

class App extends React.Component<{}, {}>{

    render() {
        return <GridComponent dataSource={data} height={315}>
            <ColumnsDirective>
                <ColumnDirective field='OrderID' headerText='Order ID' width='100' textAlign="Right"></ColumnDirective>
                <ColumnDirective field='EmployeeID' foreignKeyValue='FirstName' foreignKeyField='EmployeeID' dataSource={employeeData}  headerText='Employee Name' width='150'></ColumnDirective>
                <ColumnDirective field='Freight' headerText='Freight' width='80' textAlign="Right" format='C2'></ColumnDirective>
                <ColumnDirective field='ShipCountry' headerText='Ship Country' width='100' ></ColumnDirective>
            </ColumnsDirective>
            <Inject services={[ForeignKey]} />
        </GridComponent>
    }
};
ReactDOM.render(<App />, document.getElementById('grid'));

How to render boolean values as checkbox

To render boolean values as checkbox in columns, you need to set displayAsCheckBox property as true.

Source
Preview
index.tsx
import * as React from "react";
import * as ReactDOM from "react-dom";
import { GridComponent, Inject, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-grids';
import { data } from '../datasource.ts';
class App extends React.Component<{}, {}>{

    render() {
        return <GridComponent dataSource={data} height={315}>
            <ColumnsDirective>
                <ColumnDirective field='OrderID' headerText='Order ID' width='100' textAlign="Right"></ColumnDirective>
                <ColumnDirective field='CustomerID' headerText='Customer ID' width='120'></ColumnDirective>
                <ColumnDirective field='Freight' headerText='Freight' width='120' format="C2" textAlign="Right"></ColumnDirective>
                <ColumnDirective field='ShipCountry' headerText='Ship Country' width='150'></ColumnDirective>
                <ColumnDirective field='Verified' headerText='Verified' displayAsCheckBox={true} width='150'></ColumnDirective>
            </ColumnsDirective>
        </GridComponent>
    }
};
ReactDOM.render(<App />, document.getElementById('grid'));

See Also