Search results

How To

20 Apr 2021 / 40 minutes to read

Refresh the data source

You can add/delete the data source records through an external button. To reflect the data source changes in the grid, invoke the refresh method.

To refresh the data source:

Step 1:

Add/delete the data source record by using the following code.

Copied to clipboard
    grid.dataSource.unshift(data); // add a new record.

    grid.dataSource.splice(selectedRow, 1); // delete a record.

Step 2:

Refresh the grid after the data source change by using the refresh method.

Copied to clipboard
    grid.refresh(); // refresh the Grid.
Source
Preview
index.ts
index.css
index.html
Copied to clipboard
import { Grid } from '@syncfusion/ej2-grids';
import { Button } from '@syncfusion/ej2-buttons';
import { data } from './datasource.ts';

let grid: Grid = new Grid({
    dataSource: data,
    columns: [
        { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 120, type: 'number' },
        { field: 'CustomerID', width: 140, headerText: 'Customer ID', type: 'string' },
        { field: 'Freight', headerText: 'Freight', textAlign: 'Right', width: 120, format: 'C2' },
        { field: 'OrderDate', headerText: 'Order Date', textAlign: 'Right', width: 140, format: 'yMd' }
    ],
    height: 280
});
grid.appendTo('#Grid');

let add: Button = new Button({}, '#add');
let dele: Button = new Button({}, '#delete');

document.getElementById('add').onclick = () => {
    let data: Object = { OrderID: 10247, CustomerID: "ASDFG", Freight: 40.4, OrderDate: new Date(8367642e5) };
    (<Object[]>grid.dataSource).unshift(data); // add new record.
    grid.refresh(); // refresh the Grid.
};

document.getElementById('delete').onclick = () => {
    if (grid.getSelectedRowIndexes().length) {
        let selectedRow: number = grid.getSelectedRowIndexes()[0];
        (<Object[]>grid.dataSource).splice(selectedRow, 1); // delete the selected record.
    } else {
        alert("No records selected for delete operation");
    }
    grid.refresh(); // refresh the Grid.
};
Copied to clipboard
#container {
    visibility: hidden;
}

#loader {
  color: #008cff;
  font-family: 'Helvetica Neue','calibiri';
  font-size: 14px;
  height: 40px;
  left: 45%;
  position: absolute;
  top: 45%;
  width: 30%;
}
Copied to clipboard
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Grid</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Grid Control" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-grids/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-dropdowns/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-lists/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-calendars/styles/material.css" rel="stylesheet" />
    
    
    
    <link href="//cdn.syncfusion.com/ej2/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <button class="e-flat" id='add'>Add</button>
        <button class="e-flat" id='delete'>Delete</button>
        <div id='Grid'></div>        
    </div>
</body>
</html>

Toolbar

Create custom toolbar with drop-down list

You can create your own ToolBar items in the Grid. It can be added by defining the toolbar as HTML element ID. Actions for this ToolBar template items are defined in the toolbarClick.

To include components in the ToolBar, please ensure the following steps:

Step 1:

Initialize the template for your custom component. Using the following code add the DropDownList component to the ToolBar.

Copied to clipboard
        <div id='toolbar-template'>
            <div id='dropdown' style="margin-top:5px">
                <input type="text" tabindex="1" id='ddlelement' />
            </div>
        </div>

Step 2:

To render the DropDownList component, use the dataBound event of the Grid.

  • You can select the grid row index based on the selected data in the DropDownList. The output will appear as follows.
Source
Preview
index.ts
index.css
index.html
Copied to clipboard
import { Grid, Toolbar } from '@syncfusion/ej2-grids';
import { data } from './datasource.ts';
import { DropDownList, ChangeEventArgs } from '@syncfusion/ej2-dropdowns';
let rowIndex: any = [0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14];
Grid.Inject(Toolbar);

let grid: Grid = new Grid({
dataSource: data,
toolbarTemplate: '#toolbar-template',
dataBound: dataBound,
columns: [
    { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 120, type: 'number' },
    { field: 'CustomerID', width: 140, headerText: 'Customer ID', type: 'string' },
    { field: 'Freight', headerText: 'Freight', textAlign: 'Right', width: 120, format: 'C2' },
    { field: 'OrderDate', headerText: 'Order Date', textAlign: 'Right', width: 140, format: 'yMd' }
],
height: 200
});
grid.appendTo('#Grid');

function dataBound(): void {

let dropDownListObject: DropDownList = new DropDownList({
    // set the data to dataSource property
    dataSource: rowIndex,
    change: change,
    popupHeight :200
});
dropDownListObject.appendTo('#ddlelement');
}

function change(args: ChangeEventArgs): void {
grid.selectRow(<number>args.itemData);
}
Copied to clipboard
#container {
    visibility: hidden;
}

#loader {
  color: #008cff;
  font-family: 'Helvetica Neue','calibiri';
  font-size: 14px;
  height: 40px;
  left: 45%;
  position: absolute;
  top: 45%;
  width: 30%;
}

.e-refresh::before {
  content: '\e898';
}
Copied to clipboard
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Grid</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Grid Control" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-grids/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-dropdowns/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-lists/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-calendars/styles/material.css" rel="stylesheet" />
    
    
    
    <link href="//cdn.syncfusion.com/ej2/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Grid'></div>

        <div id='toolbar-template'>
            <div id='dropdown' style="margin-top:5px">
                <input type="text" tabindex="1" id='ddlelement' />
            </div>
        </div>
    </div>

</body>

</html>

Enable/Disable Grid and its actions

You can enable/disable the Grid and its actions by applying/removing corresponding CSS styles.

To enable/disable the grid and its actions, follow the given steps:

Step 1:

Create CSS class with custom style to override the default style of Grid.

Copied to clipboard
.disablegrid {
    pointer-events: none;
    opacity: 0.4;
}
.wrapper {
    cursor: not-allowed;
}

Step 2:

Add/Remove the CSS class to the Grid in the click event handler of Button.

Copied to clipboard
document.getElementById('primarybtn').addEventListener('click', () => {
    if (grid.element.classList.contains('disablegrid')) {
        grid.element.classList.remove('disablegrid');
        document.getElementById("GridParent").classList.remove('wrapper');
    }
    else {
        grid.element.classList.add('disablegrid');
        document.getElementById("GridParent").classList.add('wrapper');
    }
});

In the below demo, the button click will enable/disable the Grid and its actions.

Source
Preview
index.ts
index.html
Copied to clipboard
import { Grid, Edit, Toolbar, EditEventArgs, EJ2Intance } from '@syncfusion/ej2-grids';
import { Button } from '@syncfusion/ej2-buttons';
import { data } from './datasource.ts';

Grid.Inject(Edit, Toolbar);
let button: Button = new Button();
button.appendTo('#primarybtn');
let grid: Grid = new Grid({
dataSource: data,
toolbar: ['Add', 'Edit', 'Delete', 'Update', 'Cancel'],
editSettings: { allowAdding:true, allowEditing: true, allowDeleting:true },
columns: [
    { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 100, isPrimaryKey: true },
    { field: 'CustomerID', headerText: 'Customer ID', width: 120 },
    { field: 'Freight', headerText: 'Freight', textAlign: 'Right', editType: 'numericedit', width: 120, format: 'C2' },
    { field: 'ShipCountry', headerText: 'Ship Country', editType: 'dropdownedit', width: 150 }
],
height: 265
});
grid.appendTo('#Grid');
document.getElementById('primarybtn').addEventListener('click', () => {
if (grid.element.classList.contains('disablegrid')) {
    grid.element.classList.remove('disablegrid');
    document.getElementById("GridParent").classList.remove('wrapper');
}
else {
    grid.element.classList.add('disablegrid');
    document.getElementById("GridParent").classList.add('wrapper');
}
});
Copied to clipboard
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Grid</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Grid Control" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-grids/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-dropdowns/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-lists/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-calendars/styles/material.css" rel="stylesheet" />
    
    
    
    <link href="//cdn.syncfusion.com/ej2/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <button id="primarybtn">Enable/Disable Grid</button>
        <div id="GridParent">
        <div id='Grid'></div>
        </div>    
    </div>
</body>
</html>

Columns

Change column header text dynamically

You can change the column headerText dynamically through an external button.

Follow the given steps to change the header text dynamically:

Step 1:

Get the column object corresponding to the field name by using the getColumnByField method. Then, change the header text value.

Copied to clipboard
let column = grid.getColumnByField("ShipCity"); // Get column object.
column.headerText = 'Changed Text';

Step 2:

To reflect the changes in the grid header, invoke the refreshHeader method.

Copied to clipboard
grid.refreshHeader();
Source
Preview
index.ts
index.css
index.html
Copied to clipboard
import { Grid, Column } from '@syncfusion/ej2-grids';
import { data } from './datasource.ts';
import { Button } from '@syncfusion/ej2-buttons';

let grid: Grid = new Grid({
dataSource: data,
columns: [
    { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 100 },
    { field: 'CustomerID', headerText: 'Customer ID', width: 120 },
    { field: 'ShipCity', headerText: 'Ship City', width: 120 },
    { field: 'ShipName', headerText: 'Ship Name', width: 100 }
],
height: 280
});
grid.appendTo('#Grid');

let btn: Button = new Button({ cssClass: 'e-flat' }, '#change-text');

document.getElementById('change-text').addEventListener('click', () => { // changing the header text for ShipCity column.
let column: Column = grid.getColumnByField("ShipCity"); // get the JSON object of the column corresponding to the field name.
column.headerText = "Changed Text"; // assign a new header text to the column.
grid.refreshHeader();
});
Copied to clipboard
#container {
    visibility: hidden;
}

#loader {
  color: #008cff;
  font-family: 'Helvetica Neue','calibiri';
  font-size: 14px;
  height: 40px;
  left: 45%;
  position: absolute;
  top: 45%;
  width: 30%;
}
Copied to clipboard
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Grid</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Grid Control" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-dropdowns/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-lists/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-calendars/styles/material.css" rel="stylesheet" />
    
    
    
    <link href="//cdn.syncfusion.com/ej2/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    
    
    <link href="//cdn.syncfusion.com/ej2/ej2-grids/styles/material.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <button id='change-text'> Change Header Text</button>
        <div id='Grid'></div>        
    </div>
</body>
</html>

Customize column styles

You can customise the appearance of the header and content of a particular column using the customAttributes property.

To customize the grid column, follow the given steps:

Step 1:

Create a CSS class with custom style to override the default style for rowcell and headercell.

Copied to clipboard
.e-grid .e-rowcell.customcss{
background-color: #ecedee;
color: 'red';
font-family: 'Bell MT';
font-size: 20px;
}

.e-grid .e-headercell.customcss{
background-color: #2382c3;
color: white;
font-family: 'Bell MT';
font-size: 20px;
}

Step 2:

Add the custom CSS class to the specified column by using the customAttributes property.

Copied to clipboard
{ field: 'ShipCity', headerText: 'Ship City', customAttributes: {class: 'customcss'}, width: 100 },
Source
Preview
index.ts
index.css
Copied to clipboard
import { Grid } from '@syncfusion/ej2-grids';
import { data } from './datasource.ts';

let grid: Grid = new Grid({
dataSource: data,
enableHover: false,
allowSelection: false,
columns: [
    { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 100 },
    { field: 'CustomerID', headerText: 'Customer ID', width: 120 },
    { field: 'ShipCity', headerText: 'Ship City', customAttributes: { class: 'customcss' }, width: 100 },
    { field: 'ShipName', headerText: 'Ship Name', width: 100 }
],
height: 315
});
grid.appendTo('#Grid');
Copied to clipboard
#container {
    visibility: hidden;
}

#loader {
  color: #008cff;
  font-family: 'Helvetica Neue','calibiri';
  font-size: 14px;
  height: 40px;
  left: 45%;
  position: absolute;
  top: 45%;
  width: 30%;
}

.e-grid .e-rowcell.customcss{
  background-color: #ecedee;
  font-family: 'Bell MT';
	color: red;
	font-size: 20px;
}

.e-grid .e-headercell.customcss{
  background-color: #2382c3;
  color: white;
	font-family: 'Bell MT';
	font-size: 20px;
}

Display custom tooltip for columns in grid

To display custom ToolTip (EJ2 Tooltip), use the queryCellInfo event.

Render the ToolTip component for the grid cells by using the following code in the queryCellInfo event.

Copied to clipboard
function tooltip (args: QueryCellInfoEventArgs) {
let tooltip: Tooltip = new Tooltip({
    content: args.data[args.column.field].toString();
}, args.cell);
}
Source
Preview
index.ts
index.html
Copied to clipboard
import { Grid, QueryCellInfoEventArgs } from '@syncfusion/ej2-grids';
import { data } from './datasource.ts';
import { Tooltip } from '@syncfusion/ej2-popups';

let grid: Grid = new Grid({
dataSource: data,
columns: [
    { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 100 },
    { field: 'CustomerID', headerText: 'Customer ID', width: 120 },
    { field: 'ShipName', headerText: 'Ship Name', width: 140 },
    { field: 'ShipCity', headerText: 'Ship City', width: 100 },
],
queryCellInfo: tooltip,
height: 315
});
grid.appendTo('#Grid');

function tooltip(args: QueryCellInfoEventArgs): void { // event triggers on every cell render.
let tooltip: Tooltip = new Tooltip({
    content: args.data[args.column.field].toString() // add Essential JS2 tooltip for every cell.
}, <HTMLElement>args.cell);
}
Copied to clipboard
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Grid</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Grid Control" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-dropdowns/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-lists/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-calendars/styles/material.css" rel="stylesheet" />



    <link href="//cdn.syncfusion.com/ej2/ej2-splitbuttons/styles/material.css" rel="stylesheet" />


    <link href="//cdn.syncfusion.com/ej2/ej2-grids/styles/material.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id="Tooltip">
            <div id='Grid'></div>
        </div>
    </div>
</body>

</html>

Render other components in a column

You can render any component in a grid column using the template property.

To render other components in the grid, ensure the following steps:

Step 1:

Initialize the column template for your custom component.

Copied to clipboard
template:`<div>
        <select class="e-control e-dropdownlist">
            <option value="1" selected="selected">Order Placed</option>
            <option value="2">Processing</option>
            <option value="3">Delivered</option>
        </select>
    </div>`

Step 2:

Using the queryCellInfo event, you can render the DropDown component with the following code.

Copied to clipboard
function dropdown(args: QueryCellInfoEventArgs) {
    let ele=args.cell.querySelector('select');
    let drop = new DropDownList({popupHeight: 150, popupWidth: 150});
    drop.appendTo(ele);
}
Source
Preview
index.ts
index.html
Copied to clipboard
import { Grid, QueryCellInfoEventArgs } from '@syncfusion/ej2-grids';
import { data } from './datasource.ts';
import { DropDownList } from '@syncfusion/ej2-dropdowns';

let grid: Grid = new Grid({
dataSource: data,
columns: [
    {
        headerText: 'Order Status',
        template:
        `<div>
            <select class="e-control e-dropdownlist">
                <option value="1" selected="selected">Order Placed</option>
                <option value="2">Processing</option>
                <option value="3">Delivered</option>
            </select>
        </div>`, width: 140
    },
    { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 100 },
    { field: 'CustomerID', headerText: 'Customer ID', width: 120 },
    { field: 'OrderDate', headerText: 'Order Date', width: 100, format: 'yMd' },
    { field: 'ShipCity', headerText: 'Ship City', width: 100 },
],
height: 315,
queryCellInfo: dropdown
});
grid.appendTo('#Grid');

function dropdown(args: QueryCellInfoEventArgs): void {
let ele: HTMLSelectElement = args.cell.querySelector('select');
let drop: DropDownList = new DropDownList({ popupHeight: 150, popupWidth: 150 });
drop.appendTo(ele);
}
Copied to clipboard
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Grid</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Grid Control" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-dropdowns/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-lists/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-calendars/styles/material.css" rel="stylesheet" />
    
    
    
    <link href="//cdn.syncfusion.com/ej2/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    
    
    <link href="//cdn.syncfusion.com/ej2/ej2-grids/styles/material.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Grid'></div>        
    </div>
</body>
</html>

Change the orientation of the header text

You can change the orientation of the header text by using the customAttributes property.

Ensure the following steps:

Step 1:

Create a CSS class with orientation style for the grid header cell.

Copied to clipboard
.orientationcss .e-headercelldiv {
transform: rotate(90deg);
}

Step 2:

Add the custom CSS class to a particular column by using the customAttributes property.

Copied to clipboard
{ field: 'ShipCity', headerText: 'Ship City', textAlign: 'Center', customAttributes: {class: 'orientationcss'}, width: 80 },

Step 3:

Resize the header cell height by using the following code.

Copied to clipboard
function setHeaderHeight(args) {
let textWidth: number = document.querySelector(".orientationcss > div").scrollWidth;//Obtain the width of the headerText content.
let headerCell: NodeList = document.querySelectorAll(".e-headercell");
for(let i: number = 0; i < headerCell.length; i++) {
    (<HTMLElement>headerCell.item(i)).style.height = textWidth + 'px'; //Assign the obtained textWidth as the height of the headerCell.
}
}
Source
Preview
index.ts
index.css
Copied to clipboard
import { Grid, ActionEventArgs } from '@syncfusion/ej2-grids';
import { data } from './datasource.ts';

let grid: Grid = new Grid({
dataSource: data,
columns: [
    { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 100 },
    { field: 'CustomerID', headerText: 'Customer ID', width: 120 },
    { field: 'ShipCity', headerText: 'Ship City', textAlign: 'Center', customAttributes: { class: 'orientationcss' }, width: 80 },
    { field: 'ShipName', headerText: 'Ship Name', width: 100 }
],
created: setHeaderHeight,
height: 240
});
grid.appendTo('#Grid');

function setHeaderHeight(args: ActionEventArgs): void {
let textWidth: number = document.querySelector(".orientationcss > div").scrollWidth; // obtain the width of the headerText content.
let headerCell: NodeList = document.querySelectorAll(".e-headercell");
for (let i: number = 0; i < headerCell.length; i++) {
    (<HTMLElement>headerCell.item(i)).style.height = textWidth + 'px'; // assign the obtained textWidth as the height of the headerCell.
}
}
Copied to clipboard
#container {
    visibility: hidden;
}

#loader {
  color: #008cff;
  font-family: 'Helvetica Neue','calibiri';
  font-size: 14px;
  height: 40px;
  left: 45%;
  position: absolute;
  top: 45%;
  width: 30%;
}

.orientationcss .e-headercelldiv {
  transform: rotate(90deg);
}

Customize the icon for column menu

You can customize the column menu icon by overriding the default grid class .e-icons.e-columnmenu with a custom property content as mentioned below.

Copied to clipboard
.e-grid .e-columnheader .e-icons.e-columnmenu::before {
          content: "\e941";
  }

In the below sample, grid is rendered with a customized column menu icon.

Source
Preview
index.ts
index.html
Copied to clipboard
import { Grid, ColumnMenu } from '@syncfusion/ej2-grids';
import { data } from './datasource.ts';

Grid.Inject(ColumnMenu);

let grid: Grid = new Grid({
dataSource: data,
columns: [
    { field: 'OrderID', headerText: 'Order ID', width: 100 },
    { field: 'CustomerID', headerText: 'Customer ID', width: 120 },
    { field: 'ShipName', headerText: 'Ship Name', width: 140 },
    { field: 'ShipCity', headerText: 'Ship City', width: 100 },
],
showColumnMenu: true,
height: 315
});
grid.appendTo('#Grid');
Copied to clipboard
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Grid</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Grid Control" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-dropdowns/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-lists/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-calendars/styles/material.css" rel="stylesheet" />
    
    
    
    <link href="//cdn.syncfusion.com/ej2/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    
    
    <link href="//cdn.syncfusion.com/ej2/ej2-grids/styles/material.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
    <style>
        .e-grid .e-columnheader .e-icons.e-columnmenu::before {
              content: "\e941";
      }
    </style>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Grid'></div>        
    </div>
</body>
</html>

Editing

Editing with template column

You can edit the template column value by defining the field for that particular column.

In the below demo, the ShipCountry column is rendered with the template.

Source
Preview
index.ts
index.html
Copied to clipboard
import { Grid, Edit, Toolbar } from '@syncfusion/ej2-grids';
import { data } from './datasource.ts';

Grid.Inject(Edit, Toolbar);

let grid: Grid = new Grid({
dataSource: data,
toolbar: ['Add', 'Edit', 'Delete', 'Update', 'Cancel'],
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true },
columns: [
    { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 100, isPrimaryKey: true },
    { field: 'CustomerID', headerText: 'Customer ID', width: 120 },
    { field: 'Freight', headerText: 'Freight', textAlign: 'Right', editType: 'numericedit', width: 120, format: 'C2' },
    { field: 'ShipCountry', headerText: 'Ship Country', template: '#template', editType: 'dropdownedit', width: 150 }
],
height: 265
});
grid.appendTo('#Grid');
Copied to clipboard
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Grid</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Grid Control" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-grids/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-dropdowns/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-lists/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-calendars/styles/material.css" rel="stylesheet" />
    
    
    
    <link href="//cdn.syncfusion.com/ej2/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <script id="template" type="text/x-template">
            <a href="#">${ShipCountry}</a>     
        </script>
        <div id='Grid'></div>        
    </div>
</body>
</html>

Customize the edit dialog

You can customize the appearance of the edit dialog in the actionComplete event based on requestType as beginEdit or add.

In the following example, the dialog’s header text has been changed for editing and adding the records.

Source
Preview
index.ts
index.css
index.html
Copied to clipboard
import { Grid, Edit, Toolbar, DialogEditEventArgs } from '@syncfusion/ej2-grids';
import { data } from './datasource.ts';

Grid.Inject(Edit, Toolbar);

let grid: Grid = new Grid({
dataSource: data,
toolbar: ['Add', 'Edit', 'Delete'],
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Dialog' },
columns: [
    { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 100, isPrimaryKey: true },
    { field: 'CustomerID', headerText: 'Customer ID', width: 120, },
    { field: 'ShipCountry', headerText: 'Ship Country', width: 150 }
],
height: 265,
actionComplete: (args: DialogEditEventArgs) => {
    if ((args.requestType === 'beginEdit' || args.requestType === 'add')) {
        let dialog: Dialog = args.dialog;
        dialog.height = 400;
        // change the header of the dialog
        dialog.header = args.requestType === 'beginEdit' ? 'Edit Record of ' + args.rowData['CustomerID'] : 'New Customer';
    }
}
});
grid.appendTo('#Grid');
Copied to clipboard
#container {
    visibility: hidden;
}

#loader {
  color: #008cff;
  font-family: 'Helvetica Neue','calibiri';
  font-size: 14px;
  height: 40px;
  left: 45%;
  position: absolute;
  top: 45%;
  width: 30%;
}
Copied to clipboard
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Grid</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Grid Control" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-dropdowns/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-lists/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-calendars/styles/material.css" rel="stylesheet" />
    
    
    
    <link href="//cdn.syncfusion.com/ej2/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    
    
    <link href="//cdn.syncfusion.com/ej2/ej2-grids/styles/material.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Grid'></div>        
    </div>
</body>
</html>

Show or Hide columns in Dialog editing

You can show hidden columns or hide visible column’s editor in the dialog while editing the grid record using actionBegin and actionComplete events.

In the actionBegin event, based on requestType as beginEdit or add. We can show or hide the editor by using column.visible property.

In the actionComplete event, based on requestType as save. We can reset the properties back to the column state.

In the below example, we have rendered the grid columns CustomerID as hidden column and ShipCountry as visible column. In the edit mode, we have changed the CustomerID column to visible state and ShipCountry column to hidden state.

Source
Preview
index.ts
index.html
Copied to clipboard
import { Grid, Edit, Toolbar, DialogEditEventArgs } from '@syncfusion/ej2-grids';
import { data } from './datasource.ts';

Grid.Inject(Edit, Toolbar);

let grid: Grid = new Grid({
dataSource: data,
toolbar: ['Add', 'Edit', 'Delete'],
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Dialog' },
columns: [
    { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 100, isPrimaryKey: true },
    { field: 'CustomerID', headerText: 'Customer ID', width: 120, visible: false },
    { field: 'Freight', headerText: 'Freight', textAlign: 'Right', editType: 'numericedit', width: 120, format: 'C2' },
    { field: 'ShipCountry', headerText: 'Ship Country', width: 150 }
],
height: 265,
actionBegin: function(args: DialogEditEventArgs) {
    if ((args.requestType === 'beginEdit' || args.requestType === 'add')) {
        for (var i = 0; i < this.columns.length; i++) {
            if (this.columns[i].field == "CustomerID") {
                this.columns[i].visible = true;
            }
            else if (this.columns[i].field == "ShipCountry") {
                this.columns[i].visible = false;
            }
        }
    }
},
actionComplete: function(args: DialogEditEventArgs) {
    if (args.requestType === 'save') {
        for (var i = 0; i < this.columns.length; i++) {
            if (this.columns[i].field == "CustomerID") {
                this.columns[i].visible = false;
            }
            else if (this.grid.columns[i].field == "ShipCountry") {
                this.columns[i].visible = true;
            }
        }
    }
}
});
grid.appendTo('#Grid');
Copied to clipboard
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Grid</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Grid Control" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-grids/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-dropdowns/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-lists/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-calendars/styles/material.css" rel="stylesheet" />
    
    
    
    <link href="//cdn.syncfusion.com/ej2/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
    <style>
        .e-row[aria-selected="true"] .e-customizedExpandcell {
            background-color: #e0e0e0;
        }
        .e-grid.e-gridhover tr[role='row']:hover {
            background-color: #eee;
        }
        .e-expand::before {
        content: '\e5b8';
    }
    </style>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Grid'></div>        
    </div>
</body>
</html>

Cascading drop-down list with grid editing

You can achieve the Cascading DropDownList with grid Editing by using the Cell Edit Template feature.

In the below demo, Cascading DropDownList is rendered for the ShipCountry and ShipState column.

Source
Preview
index.ts
index.html
Copied to clipboard
import { Grid, Edit, Toolbar } from '@syncfusion/ej2-grids';
import { DropDownList } from '@syncfusion/ej2-dropdowns';
import { Query } from '@syncfusion/ej2-data';
import { data } from './datasource.ts';

Grid.Inject(Edit, Toolbar);

let countryElem: HTMLElement;
let countryObj: DropDownList;

let stateElem: HTMLElement;
let stateObj: DropDownList;

let country: { [key: string]: Object }[] = [
{ countryName: 'United States', countryId: '1' },
{ countryName: 'Australia', countryId: '2' }
];
let state: { [key: string]: Object }[] = [
{ stateName: 'New York', countryId: '1', stateId: '101' },
{ stateName: 'Virginia ', countryId: '1', stateId: '102' },
{ stateName: 'Washington', countryId: '1', stateId: '103' },
{ stateName: 'Queensland', countryId: '2', stateId: '104' },
{ stateName: 'Tasmania ', countryId: '2', stateId: '105' },
{ stateName: 'Victoria', countryId: '2', stateId: '106' }
];

let grid: Grid = new Grid({
dataSource: data,
toolbar: ['Add', 'Edit', 'Delete', 'Update', 'Cancel'],
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Normal' },
columns: [
    { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 100, isPrimaryKey: true, validationRules: { required: true } },
    { field: 'CustomerID', headerText: 'Customer ID', width: 120, validationRules: { required: true, minLength: 3 } },
    {
        field: 'ShipCountry', headerText: 'Ship Country', width: 120, edit: {
            create: () => {
                countryElem = document.createElement('input');
                return countryElem;
            },
            read: () => {
                return countryObj.text;
            },
            destroy: () => {
                countryObj.destroy();
            },
            write: () => {
                countryObj = new DropDownList({
                    dataSource: country,
                    fields: { value: 'countryId', text: 'countryName' },
                    change: () => {
                        stateObj.enabled = true;
                        let tempQuery: Query = new Query().where('countryId', 'equal', countryObj.value);
                        stateObj.query = tempQuery;
                        stateObj.text = null;
                        stateObj.dataBind();
                    },
                    placeholder: 'Select a country',
                    floatLabelType: 'Never'
                });
                countryObj.appendTo(countryElem);
            }
        }
    },
    {
        field: 'ShipState', headerText: 'Ship State', width: 150, edit: {
            create: () => {
                stateElem = document.createElement('input');
                return stateElem;
            },
            read: () => {
                return stateObj.text;
            },
            destroy: () => {
                stateObj.destroy();
            },
            write: () => {
                stateObj = new DropDownList({
                    dataSource: state,
                    fields: { value: 'stateId', text: 'stateName' },
                    enabled: false,
                    placeholder: 'Select a state',
                    floatLabelType: 'Never'
                });
                stateObj.appendTo(stateElem);
            }
        }
    }
],
height: 265
});
grid.appendTo('#Grid');
Copied to clipboard
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Grid</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Grid Control" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-grids/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-dropdowns/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-lists/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-calendars/styles/material.css" rel="stylesheet" />
    
    
    
    <link href="//cdn.syncfusion.com/ej2/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
    <style>
        .e-row[aria-selected="true"] .e-customizedExpandcell {
            background-color: #e0e0e0;
        }
        .e-grid.e-gridhover tr[role='row']:hover {
            background-color: #eee;
        }
        .e-expand::before {
        content: '\e5b8';
    }
    </style>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Grid'></div>        
    </div>
</body>
</html>

Provide custom data source and enabling filtering to DropDownList

You can provide data source to the DropDownList by using the columns.edit.params property.

While setting new data source using edit params, you must specify a new query property too for the dropdownlist as follows,

Copied to clipboard
{
params: {
    query: new Query(),
    dataSource: country,
    fields: { value: 'ShipCountry', text: 'ShipCountry' },
    allowFiltering: true
    }
}

You can also enable filtering for the dropdownlist by passing the allowFiltering as true to the edit params.

In the below demo, DropDownList is rendered with custom Datasource for the ShipCountry column and enabled filtering to search dropdownlist items.

Source
Preview
index.ts
index.html
Copied to clipboard
import { Grid, Edit, Toolbar } from '@syncfusion/ej2-grids';
import { Query } from '@syncfusion/ej2-data';
import { data } from './datasource.ts';

Grid.Inject(Edit, Toolbar);

let country: { [key: string]: Object }[] = [
{ ShipCountry: 'United States', countryId: '1' },
{ ShipCountry: 'Australia', countryId: '2' },
{ ShipCountry: 'India', countryId: '2' }
];

let grid: Grid = new Grid({
dataSource: data,
toolbar: ['Add', 'Edit', 'Delete', 'Update', 'Cancel'],
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Normal' },
columns: [
    { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 100, isPrimaryKey: true, validationRules: { required: true } },
    { field: 'CustomerID', headerText: 'Customer ID', width: 120, validationRules: { required: true, minLength: 3 } },
    {
        field: 'ShipCountry', headerText: 'Ship Country', width: 120, editType: 'dropdownedit', edit: {
            params: {
                query: new Query(),
                dataSource: country,
                fields: { value: 'ShipCountry', text: 'ShipCountry' },
                allowFiltering: true
            }
        }
    }
],
height: 265
});
grid.appendTo('#Grid');
Copied to clipboard
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Grid</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Grid Control" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-grids/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-dropdowns/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-lists/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-calendars/styles/material.css" rel="stylesheet" />
    
    
    
    <link href="//cdn.syncfusion.com/ej2/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
    <style>
        .e-row[aria-selected="true"] .e-customizedExpandcell {
            background-color: #e0e0e0;
        }
        .e-grid.e-gridhover tr[role='row']:hover {
            background-color: #eee;
        }
        .e-expand::before {
        content: '\e5b8';
    }
    </style>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Grid'></div>        
    </div>
</body>
</html>

Access Editor components

You can access the component instance from the component element using the ej2_instances property.

In the below demo, you can access the Editor component instance while adding or editing actions on the actionComplete event.

Source
Preview
index.ts
index.html
Copied to clipboard
import { Grid, Edit, Toolbar, EditEventArgs, EJ2Intance } from '@syncfusion/ej2-grids';
import { data } from './datasource.ts';

Grid.Inject(Edit, Toolbar);

let grid: Grid = new Grid({
dataSource: data,
actionComplete: (args: EditEventArgs) => {
    if (args.requestType === 'beginEdit' || args.requestType === 'add') {
        let tr: Element = args.row;
        let numericTextBox: Element = tr.querySelector('.e-numerictextbox'); // numeric TextBox component element
        if (numericTextBox) {
            console.log('NumericTextBox instance: ', (<EJ2Intance>numericTextBox).ej2_instances[0]); // numeric TextBox instance
        }
        let dropDownList: Element = tr.querySelector('.e-dropdownlist'); // dropDownList component element
        if (dropDownList) {
            console.log('DropDownList instance: ', (<EJ2Intance>dropDownList).ej2_instances[0]); // dropDownList instance
        }
    }
},
toolbar: ['Add', 'Edit', 'Delete', 'Update', 'Cancel'],
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true },
columns: [
    { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 100, isPrimaryKey: true },
    { field: 'CustomerID', headerText: 'Customer ID', width: 120 },
    { field: 'Freight', headerText: 'Freight', textAlign: 'Right', editType: 'numericedit', width: 120, format: 'C2' },
    { field: 'ShipCountry', headerText: 'Ship Country', editType: 'dropdownedit', width: 150 }
],
height: 265
});
grid.appendTo('#Grid');
Copied to clipboard
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Grid</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Grid Control" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-grids/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-dropdowns/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-lists/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-calendars/styles/material.css" rel="stylesheet" />
    
    
    
    <link href="//cdn.syncfusion.com/ej2/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
    <style>
        .e-row[aria-selected="true"] .e-customizedExpandcell {
            background-color: #e0e0e0;
        }
        .e-grid.e-gridhover tr[role='row']:hover {
            background-color: #eee;
        }
        .e-expand::before {
        content: '\e5b8';
    }
    </style>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Grid'></div>        
    </div>
</body>
</html>

Use Wizard like Dialog Editing

Wizard helps you to create intuitive step-by-step forms to fill. You can achieve the wizard-like editing by using the dialog template feature. It supports your own editing template by defining the editSettings.mode as Dialog and editSetting.template as SCRIPT element ID or HTML string which holds the template.

The following example demonstrates the wizard-like editing in the grid with obtrusive validation.

Source
Preview
index.ts
index.css
index.html
Copied to clipboard
import { Grid, Edit, Toolbar, DialogEditEventArgs } from '@syncfusion/ej2-grids';
import { data } from './datasource.ts';
import { DropDownList } from '@syncfusion/ej2-dropdowns';
import { DataUtil } from '@syncfusion/ej2-data';
import { CheckBox } from '@syncfusion/ej2-buttons';

Grid.Inject(Edit, Toolbar);

let countryData: {}[] = DataUtil.distinct(data, 'ShipCountry', true);

let grid: Grid = new Grid({
dataSource: data,
toolbar: ['Add', 'Edit', 'Delete'],
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Dialog', template: '#dialogtemplate' },
columns: [
    { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 100, isPrimaryKey: true, validationRules: { required: true }},
    { field: 'CustomerID', headerText: 'Customer ID', width: 120, validationRules: { required: true }},
    { field: 'ShipCountry', headerText: 'Ship Country', width: 150 }
],
height: 265,
actionComplete: (args: DialogEditEventArgs) => {
    if ((args.requestType === 'beginEdit' || args.requestType === 'add')) {
        new DropDownList({value: args.rowData.ShipCountry, popupHeight: '300px', floatLabelType: 'Always',
            dataSource: countryData, fields: {text: 'ShipCountry', value: 'ShipCountry'}, placeholder: 'Ship Country'}, args.form.elements.namedItem('ShipCountry') as HTMLInputElement);
        new CheckBox({ label: 'Verified', checked: args.rowData.Verified }, args.form.elements.namedItem('Verified'));
        // Set initail Focus
        if (args.requestType === 'beginEdit') {
            (args.form.elements.namedItem('CustomerID')as HTMLInputElement).focus();
        }
        initializeWizard();
    }
}
});
grid.appendTo('#Grid');

function initializeWizard() {
let currentTab = 0;

document.getElementById('nextBtn').onclick = function () {
    if (validate()) {
        if (this.innerHTML !== 'SUBMIT'){
            currentTab++;
            nextpre(currentTab);
        } else {
            grid.endEdit();
        }
    }
}
function validate(tab) {
    let valid: boolean = true;
        [].slice.call(document.getElementById('tab' + currentTab).querySelectorAll('[name]')).forEach(element => {
        element.form.ej2_instances[0].validate(element.name);
        if (element.getAttribute('aria-invalid') === 'true'){
            valid = false;
        }
    });
    if (!valid) {
    return false;
    }
    return true;
}
document.getElementById('prevBtn').onclick = function () {
    if (validate()) {
        currentTab--;
        nextpre(currentTab);
    }
}
}


function nextpre(current) {
let tabs: HTMLElement[] = [].slice.call(document.getElementsByClassName('tab'))
tabs.forEach(element => element.style.display = 'none');
tabs[current].style.display = '';
if(current) {
    document.getElementById('prevBtn').style.display = '';
    document.getElementById('nextBtn').innerHTML = 'SUBMIT';
} else {
    document.getElementById('prevBtn').style.display = 'none';
    document.getElementById('nextBtn').innerHTML = 'NEXT';
}
}
Copied to clipboard
#container {
    visibility: hidden;
}

#loader {
  color: #008cff;
  font-family: 'Helvetica Neue','calibiri';
  font-size: 14px;
  height: 40px;
  left: 45%;
  position: absolute;
  top: 45%;
  width: 30%;
}

.form-group.col-md-6 {
  width: 250px;
}
#ShipAddress{
  resize: vertical;
}

.e-grid .e-edit-dialog {
  min-height: 0;
}

.e-grid .e-dialog .e-footer-content {
  display: none;
}
Copied to clipboard
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Grid</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Grid Control" />
    <meta name="author" content="Syncfusion" />
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css" >
    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-grids/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-dropdowns/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-lists/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-calendars/styles/material.css" rel="stylesheet" />
    
    
    
    <link href="//cdn.syncfusion.com/ej2/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    
    
    <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Grid'></div>        
    </div>
    <script id='dialogtemplate' type="text/x-template">
        <div>
            <div id="tab0" class='tab'>
                <div class="form-row">
                    <div class="form-group col-md-6">
                        <div class="e-float-input e-control-wrapper">
                            <input id="OrderID" required name="OrderID" type="text" value=${if(isAdd)} '' ${else} ${OrderID} ${/if}  ${if(isAdd)} '' ${else} disabled ${/if} />
                            <span class="e-float-line"></span>
                            <label class="e-float-text e-label-top" for="OrderID">Order ID</label>
                        </div>
                    </div>
                </div>
                <div class="form-row">
                    <div class="form-group col-md-6">
                        <div class="e-float-input e-control-wrapper">
                            <input id="CustomerID" required name="CustomerID" type="text" value=${if(isAdd)} '' ${else} ${CustomerID} ${/if} />
                            <span class="e-float-line"></span>
                            <label class="e-float-text e-label-top" for="CustomerID">Customer ID</label>
                        </div>
                    </div>
                </div>
            </div>
            <div id=tab1 style="display: none" class='tab'>
                <div class="form-row">
                    <div class="form-group col-md-6">
                        <input type="text" name="ShipCountry" id="ShipCountry" value=${if(isAdd)} '' ${else} ${ShipCountry} ${/if} />
                    </div>
                </div>
                <div class="form-row">
                    <div class="form-group col-md-6">
                        <input type="checkbox" name="Verified" id="Verified" ${if(Verified)} checked ${/if} />
                    </div>
                </div>
            </div>
            <div id='footer'>
                <button id="prevBtn" class="e-info e-btn" type="button" style="display: none; float: left">Previous</button>
            
                <button id="nextBtn" class="e-info e-btn" type="button" style="float: right">Next</button>
            </div>
        </div>
    </script>
</body>
</html>

Using the tab inside the dialog template

You can use the tab component inside the dialog edit UI using the dialog template feature. The dialog template feature can be enabled by defining the editSettings.mode as Dialog and editSetting.template as SCRIPT element ID or HTML string which holds the template.

To include the tab components in the dialog, follow the given steps:

Step 1:

Initialize the template for your tab component.

Copied to clipboard
    <div>
    <div id="edittab"></div>
        <div id="tab1">
            <div class="form-row" >
                <div class="form-group col-md-6">
                    <div class="e-float-input e-control-wrapper">
                        <input id="OrderID" name="OrderID" type="text" value=${if(isAdd)} '' ${else} ${OrderID} ${/if} ${if(isAdd)} '' ${else} disabled ${/if} />
                        <span class="e-float-line"></span>
                        <label class="e-float-text e-label-top" for="OrderID">Order ID</label>
                    </div>
                </div>
            </div>
            <div class="form-row" >
                <div class="form-group col-md-6">
                    <div class="e-float-input e-control-wrapper">
                        <input id="CustomerID" name="CustomerID" type="text" value=${if(isAdd)} '' ${else} ${CustomerID} ${/if} />
                        <span class="e-float-line"></span>
                        <label class="e-float-text e-label-top" for="CustomerID">Customer ID</label>
                    </div>
                </div>
            </div>
            <button id='next' class='e-info e-btn' style="float: right" type='button'> next</button>
        </div>

        <div id="tab2" style='display: none'>
            <div class="form-row" >
                <div class="form-group col-md-6">
                    <input type="text" name="ShipCountry" id="ShipCountry" value=${if(isAdd)} '' ${else} ${ShipCountry} ${/if} />
                </div>
            </div>
            <div class="form-row">
                <div class="form-group col-md-6">
                    <input type="checkbox" name="Verified" id="Verified" ${if(isAdd)} '' ${else} checked ${/if} />
                </div>
            </div>
            <button id='submit' class='e-info e-btn' style="float: right" type='button'> submit</button>
        </div>
    </div>

Step 2:

To render the tab component, use the actionComplete event of the grid.

Copied to clipboard
let tabObj: Tab = new Tab({
    showCloseButton: false,
    selecting:  (e) => {if(e.isSwiped) {e.cancel = true;} if(e.selectingIndex === 1) {e.cancel = !validate(1)}},
    items: [
        { header: { 'text': 'Details' }, content: '#tab1' },
        { header: { 'text': 'Verify' }, content: '#tab2' },
    ]
});
tabObj.appendTo('#edittab');

The following example demonstrates rendering the tab control inside the edit dialog. The tab control contains two tabs. You can fill the first tab and then navigate to the second tab. The validation for first tab will be done before navigating to the second tab.

Source
Preview
index.ts
index.css
index.html
Copied to clipboard
import { Grid, Edit, Toolbar, DialogEditEventArgs } from '@syncfusion/ej2-grids';
import { data } from './datasource.ts';
import { DropDownList } from '@syncfusion/ej2-dropdowns';
import { DataUtil } from '@syncfusion/ej2-data';
import { Tab } from '@syncfusion/ej2-navigations';
import { CheckBox } from '@syncfusion/ej2-buttons';

Grid.Inject(Edit, Toolbar);

let countryData: {}[] = DataUtil.distinct(data, 'ShipCountry', true);

let grid: Grid = new Grid({
dataSource: data,
toolbar: ['Add', 'Edit', 'Delete'],
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Dialog', template: '#dialogtemplate' },
columns: [
    { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 100, isPrimaryKey: true, validationRules: { required: true } },
    { field: 'CustomerID', headerText: 'Customer ID', width: 120, validationRules: { required: true } },
    { field: 'ShipCountry', headerText: 'Ship Country', width: 150 }
],
height: 265,
actionComplete: (args: DialogEditEventArgs) => {
    if ((args.requestType === 'beginEdit' || args.requestType === 'add')) {

        let tabObj: Tab = new Tab({
            showCloseButton: false,
            selecting:  (e) => {if(e.isSwiped) {e.cancel = true;} if(e.selectingIndex === 1) {e.cancel = !validate(1)}},
            items: [
                { header: { 'text': 'Details' }, content: '#tab1' },
                { header: { 'text': 'Verify' }, content: '#tab2' },
            ]
        });
        tabObj.appendTo('#edittab');

        new DropDownList({value: args.rowData.ShipCountry, popupHeight: '200px', floatLabelType: 'Always',
            dataSource: countryData, fields: {text: 'ShipCountry', value: 'ShipCountry'}, placeholder: 'Ship Country'}, args.form.elements.namedItem('ShipCountry') as HTMLInputElement);

        new CheckBox({ label: 'Verified', checked: args.rowData.Verified }, args.form.elements.namedItem('Verified'));
        // Set initail Focus
        if (args.requestType === 'beginEdit') {
            (args.form.elements.namedItem('CustomerID')as HTMLInputElement).focus();
        }

        document.getElementById('next').onclick = () => {
            moveNext();
        }

        function validate(tab) {
            let valid: boolean = true;
             [].slice.call(document.getElementById('tab' + tab).querySelectorAll('[name]')).forEach(element => {
                element.form.ej2_instances[0].validate(element.name);
                if (element.getAttribute('aria-invalid') === 'true'){
                    valid = false;
                }
            });
            if (!valid) {
            return false;
            }
            return true;
        }

        function moveNext() {
            if (validate(1)) {
                tabObj.select(1);
            }
        }
        document.getElementById('submit').onclick = () => {
            if (validate(2)) {
                grid.endEdit();
            }
        }
    }
}
});
grid.appendTo('#Grid');
Copied to clipboard
#container {
  visibility: hidden;
}



#loader {
color: #008cff;
font-family: 'Helvetica Neue','calibiri';
font-size: 14px;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}

.form-group.col-md-6 {
width: 250px;
}
#ShipAddress{
resize: vertical;
}

.e-grid .e-edit-dialog {
min-height: 0;
}

.e-grid .e-dialog .e-footer-content {
display: none;
}

.e-grid .e-tab .e-toolbar {
  border: 0;
}

.e-tab .e-content.e-control {
overflow-x: hidden;
overflow-y: hidden;
}
Copied to clipboard
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Grid</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Grid Control" />
    <meta name="author" content="Syncfusion" />
    
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css" >
    <link href="http://npmci.syncfusion.com/packages/development/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="http://npmci.syncfusion.com/packages/development/ej2-grids/styles/material.css" rel="stylesheet" />
     <link href="http://npmci.syncfusion.com/packages/development/ej2-navigations/styles/material.css" rel="stylesheet" />
     <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Grid'></div>        
    </div>
    <script id='dialogtemplate' type="text/x-template">
       <div>
        <div id="edittab"></div>
            <div id="tab1">
                <div class="form-row" >
                    <div class="form-group col-md-6">
                        <div class="e-float-input e-control-wrapper">
                            <input id="OrderID" name="OrderID" type="text" value=${if(isAdd)} '' ${else} ${OrderID} ${/if} ${if(isAdd)} '' ${else} disabled ${/if} />
                            <span class="e-float-line"></span>
                            <label class="e-float-text e-label-top" for="OrderID">Order ID</label>
                        </div>
                    </div>
                </div>
                <div class="form-row" >
                    <div class="form-group col-md-6">
                        <div class="e-float-input e-control-wrapper">
                            <input id="CustomerID" name="CustomerID" type="text" value=${if(isAdd)} '' ${else} ${CustomerID} ${/if} />
                            <span class="e-float-line"></span>
                            <label class="e-float-text e-label-top" for="CustomerID">Customer ID</label>
                        </div>
                    </div>
                </div>
                <button id='next' class='e-info e-btn' style="float: right" type='button'> next</button>
            </div>
                
            <div id="tab2" style='display: none'>
                <div class="form-row" >
                    <div class="form-group col-md-6">
                        <input type="text" name="ShipCountry" id="ShipCountry" value=${if(isAdd)} '' ${else} ${ShipCountry} ${/if} />
                    </div>
                </div>
                <div class="form-row">
                    <div class="form-group col-md-6">
                        <input type="checkbox" name="Verified" id="Verified" ${if(isAdd)} '' ${else} checked ${/if} />
                    </div>
                </div>
                <button id='submit' class='e-info e-btn' style="float: right" type='button'> submit</button>
            </div>
        
        </div>
    </script>
</body>
</html>

Disable editing for a particular row/cell

You can disable the editing for a particular row by using the actionBegin event of Grid based on requestType as beginEdit.

In the below demo, the rows which are having the value for ShipCountry column as “France” is prevented from editing.

Source
Preview
index.ts
index.html
Copied to clipboard
import { Grid, Edit, Toolbar, EditEventArgs, EJ2Intance } from '@syncfusion/ej2-grids';
import { data } from './datasource.ts';

Grid.Inject(Edit, Toolbar);

let grid: Grid = new Grid({
dataSource: data,
actionBegin: (args: EditEventArgs) => {
    if (args.requestType === 'beginEdit') {
        if (args.rowData.ShipCountry == "France") {
            args.cancel = true;
        }
    }
},
toolbar: ['Edit', 'Update', 'Cancel'],
editSettings: { allowEditing: true },
columns: [
    { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 100, isPrimaryKey: true },
    { field: 'CustomerID', headerText: 'Customer ID', width: 120 },
    { field: 'Freight', headerText: 'Freight', textAlign: 'Right', editType: 'numericedit', width: 120, format: 'C2' },
    { field: 'ShipCountry', headerText: 'Ship Country', editType: 'dropdownedit', width: 150 }
],
height: 265
});
grid.appendTo('#Grid');
Copied to clipboard
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Grid</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Grid Control" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-grids/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-dropdowns/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-lists/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-calendars/styles/material.css" rel="stylesheet" />
    
    
    
    <link href="//cdn.syncfusion.com/ej2/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
    <style>
        .e-row[aria-selected="true"] .e-customizedExpandcell {
            background-color: #e0e0e0;
        }
        .e-grid.e-gridhover tr[role='row']:hover {
            background-color: #eee;
        }
        .e-expand::before {
        content: '\e5b8';
    }
    </style>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Grid'></div>        
    </div>
</body>
</html>

For batch mode of editing, you can use cellEdit event of Grid. In the below demo, the cells which are having the value as “France” is prevented from editing.

Source
Preview
index.ts
index.html
Copied to clipboard
import { Grid, Edit, Toolbar, EditEventArgs, EJ2Intance } from '@syncfusion/ej2-grids';
import { data } from './datasource.ts';

Grid.Inject(Edit, Toolbar);

let grid: Grid = new Grid({
dataSource: data,
cellEdit: (args: EditEventArgs) => {
    if (args.value == "France") {
        args.cancel = true;
    }
},
toolbar: ['Edit', 'Update', 'Cancel'],
editSettings: { allowEditing: true, mode: 'Batch' },
columns: [
    { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 100, isPrimaryKey: true },
    { field: 'CustomerID', headerText: 'Customer ID', width: 120 },
    { field: 'Freight', headerText: 'Freight', textAlign: 'Right', editType: 'numericedit', width: 120, format: 'C2' },
    { field: 'ShipCountry', headerText: 'Ship Country', editType: 'dropdownedit', width: 150 }
],
height: 265
});
grid.appendTo('#Grid');
Copied to clipboard
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Grid</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Grid Control" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-grids/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-dropdowns/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-lists/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-calendars/styles/material.css" rel="stylesheet" />
    
    
    
    <link href="//cdn.syncfusion.com/ej2/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
    <style>
        .e-row[aria-selected="true"] .e-customizedExpandcell {
            background-color: #e0e0e0;
        }
        .e-grid.e-gridhover tr[role='row']:hover {
            background-color: #eee;
        }
        .e-expand::before {
        content: '\e5b8';
    }
    </style>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Grid'></div>        
    </div>
</body>
</html>

Perform Grid actions by keyboard shortcut keys

Using keyboard shortcuts, Grid performs navigation and actions.

In addition, You can also perform grid actions with custom keyboard shortcuts. This operation has to be achieved outside of the grid with the help of keydown event.

The following example demonstrates on Adding a new row when Enter key is pressed in the grid.

Source
Preview
index.ts
index.html
Copied to clipboard
import { Grid, Edit, Toolbar } from '@syncfusion/ej2-grids';
import { data } from './datasource.ts';

Grid.Inject(Edit, Toolbar);

let grid: Grid = new Grid({
dataSource: data,
toolbar: ['Add', 'Edit', 'Delete', 'Update', 'Cancel'],
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true},
columns: [
    { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 100, isPrimaryKey: true, validationRules: { required: true }},
    { field: 'CustomerID', headerText: 'Customer ID', width: 120 },
    { field: 'ShipCountry', headerText: 'Ship Country', width: 150 }
],
height: 265
});
grid.appendTo('#Grid');

grid.element.addEventListener("keydown", keyDownHandler);

function keyDownHandler(e: any): void {
if(e.keyCode === 13 ) {
    let gridIns: any = document.getElementById("Grid").ej2_instances[0];
    gridIns.addRecord();
}
}
Copied to clipboard
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Grid</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Grid Control" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-grids/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-dropdowns/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-lists/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-calendars/styles/material.css" rel="stylesheet" />
    
    
    
    <link href="//cdn.syncfusion.com/ej2/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
    <style>
        .e-row[aria-selected="true"] .e-customizedExpandcell {
            background-color: #e0e0e0;
        }
        .e-grid.e-gridhover tr[role='row']:hover {
            background-color: #eee;
        }
        .e-expand::before {
        content: '\e5b8';
    }
    </style>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Grid'></div>        
    </div>
</body>
</html>

Make a cell editable on a single click with batch editing

You can make a cell editable on a single click with batch mode of editing in Grid, by using the editCell method.

Bind the click event for Grid and in the click event handler call the editCell method, based on the clicked target element.

Source
Preview
index.ts
index.html
Copied to clipboard
import { Grid, Edit, Toolbar, EditEventArgs, EJ2Intance } from '@syncfusion/ej2-grids';
import { data } from './datasource.ts';

Grid.Inject(Edit, Toolbar);

document.getElementById("Grid").addEventListener("click", (e) => {
if((event.target as Element).classList.contains("e-rowcell")){
    let gridObj: Grid = (document.getElementsByClassName("e-grid")[0] as Element).ej2_instances[0];
    let index: number = parseInt((event.target as Element).getAttribute("Index"));
    let colindex:number = parseInt((event.target as Element).getAttribute("aria-colindex"));
    let field:string = gridObj.getColumns()[colindex].field;
    gridObj.editModule.editCell(index, field);
}
});

let grid: Grid = new Grid({
dataSource: data,
toolbar: ['Add', 'Delete', 'Update', 'Cancel'],
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Batch' },
columns: [
    { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 100, isPrimaryKey: true },
    { field: 'CustomerID', headerText: 'Customer ID', width: 120 },
    { field: 'Freight', headerText: 'Freight', textAlign: 'Right', editType: 'numericedit', width: 120, format: 'C2' },
    { field: 'ShipCountry', headerText: 'Ship Country', editType: 'dropdownedit', width: 150 }
],
height: 265
});
grid.appendTo('#Grid');
Copied to clipboard
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Grid</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Grid Control" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-grids/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-dropdowns/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-lists/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-calendars/styles/material.css" rel="stylesheet" />
    
    
    
    <link href="//cdn.syncfusion.com/ej2/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
    <style>
        .e-row[aria-selected="true"] .e-customizedExpandcell {
            background-color: #e0e0e0;
        }
        .e-grid.e-gridhover tr[role='row']:hover {
            background-color: #eee;
        }
        .e-expand::before {
        content: '\e5b8';
    }
    </style>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Grid'></div>        
    </div>
</body>
</html>

Filter

Customizing filter menu operators list

You can customize the default filter operator list by defining the filterSettings.operators property. The available options are:

  • stringOperator- Defines the customized string operator list.
  • numberOperator - Defines the customized number operator list.
  • dateOperator - Defines the customized date operator list.
  • booleanOperator - Defines the customized Boolean operator list.

The following sample illustrates customizing the string filter operators.

Source
Preview
index.ts
index.html
Copied to clipboard
import { Grid, Filter } from '@syncfusion/ej2-grids';
import { data } from './datasource.ts';

Grid.Inject(Filter);

let grid: Grid = new Grid({
dataSource: data,
allowFiltering: true,
filterSettings: {type:'Menu',
    operators: {
        stringOperator: [
                { value: 'startsWith', text: 'starts with' },
                { value: 'endsWith', text: 'ends with' },
                { value: 'contains', text: 'contains' }],
        }
},
columns: [
    { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 100 },
    { field: 'CustomerID', headerText: 'Customer ID', width: 120 },
    { field: 'ShipCity', headerText: 'Ship City', width: 100 },
    { field: 'ShipName', headerText: 'Ship Name', width: 100 }
],
height: 273
});
grid.appendTo('#Grid');
Copied to clipboard
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Grid</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Grid Control" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-grids/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-dropdowns/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-lists/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-calendars/styles/material.css" rel="stylesheet" />
    
    
    
    <link href="//cdn.syncfusion.com/ej2/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
    <style>
        .e-row[aria-selected="true"] .e-customizedExpandcell {
            background-color: #e0e0e0;
        }
        .e-grid.e-gridhover tr[role='row']:hover {
            background-color: #eee;
        }
        .e-expand::before {
        content: '\e5b8';
    }
    </style>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Grid'></div>        
    </div>
</body>
</html>

Sort

Perform single/multi sorting dynamically

You can perform single-column or multi-column sorting dynamically through an external button.

To perform single-column sorting, use the sortColumn method of Grid.

Copied to clipboard
document.getElementById('SingleSort').addEventListener('click', () => {
    grid.sortColumn("OrderID","Descending")
});

To perform multi-column sorting, you need to push the columns to be sorted into the sortSettings.columns.

Copied to clipboard
document.getElementById('MultiSort').addEventListener('click', () => {
    grid.sortModule.sortSettings.columns.push({ field: 'ShipCity',  direction: 'Ascending' },{ field: 'ShipName', direction: 'Descending' });
    grid.refresh();
});

In the below demo, click on the corresponding button to perform single-column or multi-column sorting.

Source
Preview
index.ts
index.html
Copied to clipboard
import { Grid, Column, Sort } from '@syncfusion/ej2-grids';
import { data } from './datasource.ts';
import { Button } from '@syncfusion/ej2-buttons';

Grid.Inject(Sort)

let grid: Grid = new Grid({
dataSource: data,
allowSorting: true,
columns: [
    { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 100 },
    { field: 'CustomerID', headerText: 'Customer ID', width: 120 },
    { field: 'ShipCity', headerText: 'Ship City', width: 120 },
    { field: 'ShipName', headerText: 'Ship Name', width: 100 }
],
height: 280
});
grid.appendTo('#Grid');

let singlesort: Button = new Button({ cssClass: 'e-flat' }, '#SingleSort');
let multisort: Button = new Button({ cssClass: 'e-flat' }, '#MultiSort');

document.getElementById('SingleSort').addEventListener('click', () => {
grid.sortColumn("OrderID","Descending")
});

document.getElementById('MultiSort').addEventListener('click', () => {
grid.sortModule.sortSettings.columns.push({ field: 'ShipCity',  direction: 'Ascending' },{ field: 'ShipName', direction: 'Descending' });
grid.refresh();
});
Copied to clipboard
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Grid</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Grid Control" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-dropdowns/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-lists/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-calendars/styles/material.css" rel="stylesheet" />
    
    
    
    <link href="//cdn.syncfusion.com/ej2/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    
    
    <link href="//cdn.syncfusion.com/ej2/ej2-grids/styles/material.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <button id='SingleSort'> Sort <b>OrderID</b> column</button>
        <button id='MultiSort'> Sort <b>CustomerID</b> and <b>ShipName</b> columns</button>
        <div id='Grid'></div>        
    </div>
</body>
</html>

Dynamically clear sort for particular/entire sorted columns in Grid

You can clear the sorting for a particular column or the entire sorted columns in Grid dynamically through an external button.

To clear sort for a particular column, you need to splice the particular column from the sortSettings.columns.

Copied to clipboard
document.getElementById('SingleClearSort').addEventListener('click', () => {
    let column: Column = grid.sortModule.sortSettings.columns;
    for(let i=0;i < column.length;i++){
        if(column[i].field === "OrderID") {
            column.splice(i,1);
            grid.refresh();
        }
    }
});

To clear sorting for all the sorted columns, use the clearSorting method of Grid.

Copied to clipboard
document.getElementById('MultiClearSort').addEventListener('click', () => {
    grid.clearSorting();
});

In the below demo, click on the corresponding button to clear sort for particular or entire sorted columns in Grid.

Source
Preview
index.ts
index.html
Copied to clipboard
import { Grid, Column, Sort } from '@syncfusion/ej2-grids';
import { data } from './datasource.ts';
import { Button } from '@syncfusion/ej2-buttons';

Grid.Inject(Sort)

let grid: Grid = new Grid({
dataSource: data,
allowSorting:true,
sortSettings: { columns: [{ field: 'OrderID', direction: 'Ascending' }, { field: 'CustomerID', direction: 'Descending' },{ field: 'ShipCity', direction: 'Ascending' },{ field: 'ShipName', direction: 'Descending' }] },
columns: [
    { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 100 },
    { field: 'CustomerID', headerText: 'Customer ID', width: 120 },
    { field: 'ShipCity', headerText: 'Ship City', width: 120 },
    { field: 'ShipName', headerText: 'Ship Name', width: 100 }
],
height: 280
});
grid.appendTo('#Grid');

let singleclear: Button = new Button({ cssClass: 'e-flat' }, '#SingleClearSort');
let multiclear: Button = new Button({ cssClass: 'e-flat' }, '#MultiClearSort');

document.getElementById('SingleClearSort').addEventListener('click', () => {
let column: Column = grid.sortModule.sortSettings.columns;
for(let i=0;i < column.length;i++){
    if(column[i].field === "OrderID") {
        column.splice(i,1);
        grid.refresh();
    }
}
});

document.getElementById('MultiClearSort').addEventListener('click', () => {
grid.clearSorting();
});
Copied to clipboard
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Grid</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Grid Control" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-dropdowns/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-lists/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-calendars/styles/material.css" rel="stylesheet" />
    
    
    
    <link href="//cdn.syncfusion.com/ej2/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    
    
    <link href="//cdn.syncfusion.com/ej2/ej2-grids/styles/material.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <button id='SingleClearSort'> Clear the sort for <b>OrderID</b> column</button>
        <button id='MultiClearSort'> Clear sorting for entire sorted columns</button>
        <div id='Grid'></div>        
    </div>
</body>
</html>

Foreign Key

Use Edit Template in Foreign Key Column

By default, the foreign key column uses the drop-down component for editing. You can render other than the drop-down component by using the column.edit property. The following example demonstrates the way of using edit template in the foreign column.

In the following code example, the Employee Name is a foreign key column. When editing, the AutoComplete component is rendered instead of drop-down list.

Source
Preview
index.ts
index.html
Copied to clipboard
import { createElement } from '@syncfusion/ej2-base';
import { Grid, ForeignKey, Edit, Toolbar } from '@syncfusion/ej2-grids';
import { AutoComplete } from '@syncfusion/ej2-dropdowns';
import { DataManager, Query } from '@syncfusion/ej2-data';
import { data, employeeData } from './datasource.ts';

Grid.Inject(ForeignKey, Edit, Toolbar);

let autoComplete: AutoComplete;

let grid: Grid = new Grid(
    {
        dataSource: data,
        editSettings: { allowEditing: true },
        toolbar: ['Edit', 'Update', 'Cancel'],
        columns: [
            { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 100, isPrimaryKey: true },
            // Foreign column
            {
                field: 'EmployeeID', headerText: 'Employee Name', width: 150, foreignKeyValue: 'LastName', dataSource: employeeData,
                edit: {
                        create: () => { // to create input element
                            return createElement('input');
                        },
                        read: () => { // return edited value to update data source
                            let value: Object[] = new DataManager(employeeData).executeLocal(new Query().where('LastName', 'equal', autoComplete.value));
                            return value.length && value[0]['EmployeeID']; // to convert foreign key value to local value.
                        },
                        destroy: () => { // to destroy the custom component.
                            autoComplete.destroy();
                        },
                        write: (args: { rowData: Object, column: Column, foreignKeyData: Object }) => { // to show the value for custom component
                            autoComplete = new AutoComplete({
                                dataSource: employeeData,
                                fields: { value: args.column.foreignKeyValue },
                                value: args.foreignKeyData[0][args.column.foreignKeyValue]
                            });
                            autoComplete.appendTo(args.element);
                        }
                    }
            },
            { field: 'Freight', headerText: 'Freight', width: 100, textAlign: 'Right'},
            { field: 'ShipName', headerText: 'Ship Name', width: 180 }
        ],
        height: 265
    });
grid.appendTo('#Grid');
Copied to clipboard
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Grid</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Grid Control" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-grids/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-dropdowns/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-lists/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-calendars/styles/material.css" rel="stylesheet" />
    
    
    
    <link href="//cdn.syncfusion.com/ej2/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Grid'></div>        
    </div>
</body>
</html>

Customize filter UI in foreign key column

You can create your own filtering UI by using column.filter property. The following example demonstrates the way to create a custom filtering UI in the foreign column.

In the following example, The Employee Name is a foreign key column. DropDownList is rendered using Filter UI.

Source
Preview
index.ts
index.html
Copied to clipboard
import { createElement } from '@syncfusion/ej2-base';
import { DataManager } from '@syncfusion/ej2-data';
import { Grid, ForeignKey, Filter } from '@syncfusion/ej2-grids';
import { data, fEmployeeData } from './datasource.ts';
import { DropDownList } from '@syncfusion/ej2-dropdowns';

Grid.Inject(ForeignKey, Filter);

let grid: Grid = new Grid(
{
    dataSource: data,
    allowFiltering: true,
    filterSettings: {type: 'Menu'},
    columns: [
        { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 100 },
        // Foreign column
        {
            field: 'EmployeeID', headerText: 'Employee Name', width: 150, foreignKeyValue: 'FirstName', dataSource: fEmployeeData,
            filter: {
                    ui: {
                        create: (args: { target: Element, column: Object }) => {
                            let flValInput: HTMLElement = createElement('input', { className: 'flm-input' });
                            args.target.appendChild(flValInput);
                            this.dropInstance = new DropDownList({
                                dataSource: new DataManager(fEmployeeData),
                                fields: { text: 'FirstName', value: 'EmployeeID' },
                                placeholder: 'Select a value',
                                popupHeight: '200px'
                            });
                            this.dropInstance.appendTo(flValInput);
                        },
                        write: (args: {
                            column: Object, target: Element, parent: any,
                            filteredValue: number | string
                        }) => {
                            this.dropInstance.text = args.filteredValue || '';
                        },
                        read: (args: { target: Element, column: any, operator: string, fltrObj: Filter }) => {
                            args.fltrObj.filterByColumn(args.column.field, args.operator, this.dropInstance.text);
                        }
                    }
                }
        },
        { field: 'Freight', headerText: 'Freight', width: 100, textAlign: 'Right'},
        { field: 'ShipName', headerText: 'Ship Name', width: 180 }
    ],
    height: 315
});
grid.appendTo('#Grid');
Copied to clipboard
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Grid</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Grid Control" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-grids/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-dropdowns/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-lists/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-calendars/styles/material.css" rel="stylesheet" />
    
    
    
    <link href="//cdn.syncfusion.com/ej2/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Grid'></div>        
    </div>
</body>
</html>

Use filter bar template in foreign key column

You can use the filter bar template in foreign key column by defining the column.filterBarTemplate property. The following example demonstrates the way to use filter bar template in foreign column.

In the following example, The Employee Name is a foreign key column. This column header shows the custom filter bar template and you can select filter value by using the DropDown options.

Source
Preview
index.ts
index.html
Copied to clipboard
import { Grid, ForeignKey, Filter } from '@syncfusion/ej2-grids';
import { data, fEmployeeData } from './datasource.ts';
import { createElement } from '@syncfusion/ej2-base';
import { DropDownList } from '@syncfusion/ej2-dropdowns';
import { DataManager } from '@syncfusion/ej2-data';

Grid.Inject(ForeignKey, Filter);

let grid: Grid = new Grid(
{
    dataSource: data,
    allowFiltering: true,
    columns: [
        { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 100 },
        // Foreign column
        {
            field: 'EmployeeID', headerText: 'Employee Name', width: 150, foreignKeyValue: 'FirstName', dataSource: fEmployeeData,
            filterBarTemplate: {
                create: (args: { element: Element, column: Column }) =>
                    return createElement('input', { className: 'flm-input' });;
                },
                write: (args: { element: Element, column: Column }) => {
                    fEmployeeData.splice(0, 0, {'FirstName': 'All'}); // for clear filtering
                    let dropInstance: DropDownList = new DropDownList({
                        dataSource: new DataManager(fEmployeeData),
                        fields: { text: 'FirstName' },
                        placeholder: 'Select a value',
                        popupHeight: '200px',
                        index: 0,
                        change: (args) => {
                            if (args.value !== 'All') {
                                grid.filterByColumn('EmployeeID', 'equal', args.value);
                            }
                            else {
                                grid.removeFilteredColsByField('EmployeeID');
                            }
                        }
                    });
                    dropInstance.appendTo(args.element);
                }
            }
        },
        { field: 'Freight', headerText: 'Freight', width: 100, textAlign: 'Right'},
        { field: 'ShipName', headerText: 'Ship Name', width: 180 }
    ],
    height: 260
});
grid.appendTo('#Grid');