Column template in EJ2 TypeScript Grid control

24 Jun 202424 minutes to read

Grid control provides a template option that allows you to display custom elements in a column instead of the field value. This can be useful when you need to display images, buttons, or other custom content within a column.

When using template columns, they are primarily meant for rendering custom content and may not provide built-in support for grid actions like sorting, filtering, editing. It is must to define the field property of the column to perform any grid actions.

Render image in a column

To render an image in a grid column, you need to define a template for the column using the template property. The template property expects the HTML element or a function that returns the HTML element.

The following example demonstrates how to define a template for the Employee Image field that displays an image element. The template property is set to the HTML element that contains an image tag. You have utilized the src and alt attributes to an image tag.

import { Grid } from '@syncfusion/ej2-grids';
import { employeeData } from './datasource.ts';

let grid: Grid = new Grid({
    dataSource: employeeData,
    columns: [
        {
            headerText: 'Employee Image', textAlign: 'Center',
            template: '#template', width: 150
        },
        { field: 'FirstName', headerText: 'First Name', width: 100 },
        { field: 'LastName', headerText: 'Last Name', width: 100 },
        { field: 'City', headerText: 'City', width: 100 }
    ],
    height: 315
});
grid.appendTo('#Grid');
<!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="https://cdn.syncfusion.com/ej2/28.1.33/ej2-base/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-buttons/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-popups/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-navigations/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-dropdowns/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-lists/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-inputs/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-calendars/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-splitbuttons/styles/bootstrap5.css" rel="stylesheet" /> 
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-grids/styles/bootstrap5.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <script id="template" type="text/x-template">
            <div class="image">
                <img src="${EmployeeID}.png" alt="${EmployeeID}" />
            </div>
        </script>
        <div id='Grid'></div>        
    </div>
</body>
</html>

The template option allows to define any HTML content within a column.

The Grid control provides support for rendering hyperlink columns and performing routing on click using the template property. This feature is useful when displaying data that requires a link to another page or website.

The following example demonstrates, how to render hyperlink column in the Grid using the template property of the column. To define a template for the column, you can use the template with the a tag to create the hyperlink.

import { Grid } from '@syncfusion/ej2-grids';
import { employeeData } from './datasource.ts';

let grid: Grid = new Grid({
    dataSource: employeeData,
    columns: [
        { field: 'EmployeeID', headerText: 'Employee ID', width: 90 },
        { field: 'LastName', headerText: 'Last Name', width: 150 },
        { field: 'FirstName', headerText: 'First Name', width: 150, template: '#template' }
    ],
    height: 315
});
grid.appendTo('#Grid');
<!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="https://cdn.syncfusion.com/ej2/28.1.33/ej2-base/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-buttons/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-popups/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-navigations/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-dropdowns/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-lists/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-inputs/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-calendars/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-splitbuttons/styles/bootstrap5.css" rel="stylesheet" /> 
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-grids/styles/bootstrap5.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <script id="template" type="text/x-template">
            <div >
                <a href="https://www.google.com/search?q=${FirstName}" target="_blank"  >
                ${FirstName}
                </a>
            </div>
          </script>
        <div id='Grid'></div>        
    </div>
</body>
</html>

The window.open() method is a built-in JavaScript function that opens a new browser window or tab with the specified URL.

Render other controls in a column

The column template has options to render a custom control in a grid column instead of a field value.

Render LineChart control in a column

The LineChart control of Syncfusion provides an elegant way to represent and compare data over time. It displays data points connected by straight line segments to visualize trends in data.

In the following example, we have rendered the Sparkline Chart control in the Grid column by defining the template property.

import { Grid, QueryCellInfoEventArgs } from '@syncfusion/ej2-grids';
import { employeeData } from './datasource.ts';
import { Sparkline } from '@syncfusion/ej2-charts';

let grid: Grid = new Grid({
    dataSource: employeeData,
    queryCellInfo: queryCellInfo,
    columns: [
        { field: 'EmployeeID',headerText: 'Employee ID',textAlign: 'Right',width: 90},
        { field: 'FirstName', headerText: 'First Name', width: 150 },
        { headerText: 'Employee Performance Rating', template: '#columnTemplate', width: 280 }

    ],
    height: 315,
});
grid.appendTo('#Grid');

let lineData: object[] = [
  [0, 6, -4, 1, -3, 2, 5],
  [5, -4, 6, 3, -1, 2, 0],
  [6, 4, 0, 3, -2, 5, 1],
  [4, -6, 3, 0, 1, -2, 5],
  [3, 5, -6, -4, 0, 1, 2],
  [1, -3, 4, -2, 5, 0, 6],
  [2, 4, 0, -3, 5, -6, 1],
  [5, 4, -6, 3, 1, -2, 0],
  [0, -6, 4, 1, -3, 2, 5],
  [6, 4, 0, -3, 2, -5, 1],
];
  
function queryCellInfo(args: QueryCellInfoEventArgs) {
  if (args.column.headerText === 'Employee Performance Rating') {
    var sparklineContainer = args.cell.querySelector('#spkline' + args.data.EmployeeID);
    let line: Sparkline = new Sparkline({
      height: '50px',
      width: '90%',
      lineWidth: 2,
      valueType: 'Numeric',
      fill: '#3C78EF',
      dataSource: getSparkData('line', args.data.EmployeeID),
    });
    line.appendTo(sparklineContainer);
  }
}
  
  function getSparkData(type: string,count: number) {
    return lineData[count] as number[];;
  }
<!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="https://cdn.syncfusion.com/ej2/28.1.33/ej2-base/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-buttons/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-popups/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-navigations/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-dropdowns/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-lists/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-inputs/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-calendars/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-splitbuttons/styles/bootstrap5.css" rel="stylesheet" /> 
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-grids/styles/bootstrap5.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
                <script type="text/x-template" id="columnTemplate" >
                    <div id="spkline${EmployeeID}" ></div>
                </script>
        <div id="Grid"></div>           
    </div>
</body>
</html>

Render ColorPicker control in a column

The ColorPicker control of Syncfusion provides a user-friendly way to select colors from a pre-defined color palette or custom colors. It can be used in a variety of scenarios such as picking a theme color or changing the color of an element on a page.

In the following code, we rendered the ColorPicker control in the Grid column by defining the template property.

function colorPicker(args: QueryCellInfoEventArgs) {
  let inputElement: HTMLSelectElement  = args.cell.querySelector('input')
    let colorPickerObject: ColorPicker = new ColorPicker({
      type: 'color',
      mode: 'Palette',
      change: change,
    });
    colorPickerObject.appendTo(inputElement);
}
import { Grid, QueryCellInfoEventArgs } from '@syncfusion/ej2-grids';
import { employeeData } from './datasource.ts';
import { ColorPicker, ColorPickerEventArgs } from '@syncfusion/ej2-inputs';

let grid: Grid = new Grid({
    dataSource: employeeData,
    enableHover: false,
    queryCellInfo: colorPicker,
    columns: [
      { field: 'FirstName', headerText: 'First Name', width: 100 },
      { field: 'LastName', headerText: 'Last Name', width: 100 },
      { field: 'City', headerText: 'City', width: 100 },
      { headerText: 'Change the color of row',textAlign:'Center', template: '#columnTemplate', width: 120 },
    ],
    height: 315,
});
grid.appendTo('#Grid');

function colorPicker(args: QueryCellInfoEventArgs) {
  let inputElement: HTMLSelectElement  = args.cell.querySelector('input')
    let colorPickerObject: ColorPicker = new ColorPicker({
      type: 'color',
      mode: 'Palette',
      change: change,
    });
    colorPickerObject.appendTo(inputElement);
}

function change(args: ColorPickerEventArgs) {
  let selectedRows = grid.getSelectedRows() as HTMLElement[]; 
  for (let row of selectedRows) {
    row.style.backgroundColor = args.value as string;
}
  grid.clearSelection();
}
<!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="https://cdn.syncfusion.com/ej2/28.1.33/ej2-base/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-buttons/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-popups/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-navigations/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-dropdowns/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-lists/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-inputs/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-calendars/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-splitbuttons/styles/bootstrap5.css" rel="stylesheet" /> 
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-grids/styles/bootstrap5.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <script type="text/x-template" id="columnTemplate" >
            <input id="element" type="color" />
        </script>
        <div id="Grid"></div>           
    </div>
</body>
</html>

Render DropDownList control in a column

To render a custom control in a grid column, you need to define a template for the column using the template property. In the following code, we rendered the DropDownList control in the Order Status column by defining the template property.

function dropdown(args: QueryCellInfoEventArgs) {
   if (args.column.field === 'OrderStatus') {
      let drop = new DropDownList({
          dataSource: dropData,
          value: args.data['OrderStatus'],
          popupHeight: 150,
          popupWidth: 150,
      });
      drop.appendTo(args.cell.querySelector('#dropElement'));
  }
}
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: [
        { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 90 },
        { field: 'CustomerID', headerText: 'Customer ID', width: 100 },
        { field: 'Freight', headerText: 'Freight', width: 90, format: 'C2' },
        { field: 'OrderStatus', headerText: 'Order Status', template: '#columnTemplate', width: 200 },
    ],
    height: 315,
    queryCellInfo: dropdown
});
grid.appendTo('#Grid');

let dropData = ['Order Placed', 'Processing', 'Delivered'];

function dropdown(args: QueryCellInfoEventArgs){
    if (args.column.field === 'OrderStatus') {
        let drop = new DropDownList({
            dataSource: dropData,
            value: args.data['OrderStatus'],
            popupHeight: 150,
            popupWidth: 150,
        });
        drop.appendTo(args.cell.querySelector('#dropElement'));
    }
}
<!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="https://cdn.syncfusion.com/ej2/28.1.33/ej2-base/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-buttons/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-popups/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-navigations/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-dropdowns/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-lists/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-inputs/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-calendars/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-splitbuttons/styles/bootstrap5.css" rel="stylesheet" />  
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-grids/styles/bootstrap5.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <script type="text/x-template" id="columnTemplate" >
            <div id="dropElement" ></div>
          </script>
        <div id='Grid'></div>        
    </div>
</body>
</html>

Render Chip control in a column

The Grid control provides support for rendering Chips control in a column using the template property. This feature is useful when displaying data that requires a chip control to be rendered in a column.

In the following code, we rendered the Chips control in the Grid First Name column by defining the template property.

  function queryCellInfo(args: QueryCellInfoEventArgs ) {
      if (args.column.field === 'FirstName') {
      var chip = new ChipList({
        text: args.data[args.column.field],
      });
      chip.appendTo(args.cell.querySelector('#chipElement'));
    }
  }
import { Grid, QueryCellInfoEventArgs } from '@syncfusion/ej2-grids';
import { employeeData } from './datasource.ts';
import { ChipList } from '@syncfusion/ej2-buttons';

let grid: Grid = new Grid({
    dataSource: employeeData,
    enableHover: false,
    queryCellInfo: queryCellInfo,
    columns: [
        { field: 'LastName', headerText: 'Last Name', width: 90 },
        { field: 'City', headerText: 'City', width: 150 },
        { field: 'FirstName', headerText: 'First Name', template: '#columnTemplate', width: 90 },
      ],
    height: 315,
  });
  grid.appendTo('#Grid');
  
  function queryCellInfo(args: QueryCellInfoEventArgs ) {
    if (args.column.field === 'FirstName') {
      let chip: ChipList = new ChipList({
        text: args.data[args.column.field],
      });
      chip.appendTo(args.cell.querySelector('#chipElement'));
    }
  }
<!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="https://cdn.syncfusion.com/ej2/28.1.33/ej2-base/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-buttons/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-popups/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-navigations/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-dropdowns/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-lists/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-inputs/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-calendars/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-splitbuttons/styles/bootstrap5.css" rel="stylesheet" /> 
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-grids/styles/bootstrap5.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <script type="text/x-template" id="columnTemplate" >
            <div id="chipElement" ></div>
        </script>
        <div id="Grid"></div>           
    </div>
</body>
</html>

Render ProgressBar control in a column

The Syncfusion Grid control supports rendering the Progress Bar control within a column using the template property. Displaying the Progress Bar control in a grid column allows users to visually track the progress of tasks or operations associated with specific records. This feature is particularly useful for applications involving processes such as data loading, task completion, or other progressive activities.

In the following code, the Progress Bar control render in the Grid Freight column by defining the template property.

function queryCellInfo(args: QueryCellInfoEventArgs ) {
  if (args.column.field === 'Freight') {
    let percentageProgress = new ProgressBar({
      type: 'Linear',
      height: '60',
      value: args.data['Freight'],
      trackThickness:24,
      progressThickness:20
    });
    percentageProgress.appendTo(args.cell.querySelector('#progressBarElement'));
  }
}
import { Grid, QueryCellInfoEventArgs } from '@syncfusion/ej2-grids';
import { data } from './datasource.ts';
import { ProgressBar } from '@syncfusion/ej2-progressbar';

let grid: Grid = new Grid({
  dataSource: data,
  columns: [
      { field: 'OrderID', headerText: 'Order ID', width: 150 },
      { field: 'CustomerID', headerText: 'Customer Name', width: 150 },
      { field: 'Freight', headerText: 'Freight', template: '#columnTemplate', width: 150 },
  ],
  queryCellInfo: queryCellInfo,
  height: 315,
});
grid.appendTo('#Grid');

function queryCellInfo(args: QueryCellInfoEventArgs ) {
  if (args.column.field === 'Freight') {
    let percentageProgress = new ProgressBar({
      type: 'Linear',
      height: '60',
      value: args.data['Freight'],
      trackThickness:24,
      progressThickness:20
    });
    percentageProgress.appendTo(args.cell.querySelector('#progressBarElement'));
  }
}
<!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="https://cdn.syncfusion.com/ej2/28.1.33/ej2-base/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-buttons/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-popups/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-navigations/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-dropdowns/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-lists/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-inputs/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-calendars/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-splitbuttons/styles/bootstrap5.css" rel="stylesheet" /> 
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-grids/styles/bootstrap5.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
      <script type="text/x-template" id="columnTemplate" >
        <div id="progressBarElement" ></div>
      </script>
        <div id="Grid"></div>           
    </div>
</body>
</html>

Using condition template

The conditional column template allows you to display template elements based on specific conditions.

The following example demonstrates how to use the template property with the template element and add the condition to render the checkbox based on the value of the Discontinued field. The Discontinued field will render a checkbox in each row for which the value of the Discontinued field is true.

  <script id="template" type="text/x-template">
            <div class="template_checkbox">
                ${if(Discontinued)}
                <input type="checkbox" checked> ${else}
                <input type="checkbox"> ${/if}
            </div>
        </script>
import { Grid } from '@syncfusion/ej2-grids';
import { categoryData } from './datasource.ts';

let grid: Grid = new Grid({
        dataSource: categoryData,
        columns: [
            {
                headerText: 'Discontinued', textAlign: 'Center',
                template: '#template', width: 150
            },
            { field: 'ProductID', headerText: 'Product ID', textAlign: 'Right', width: 150 },
            { field: 'CategoryName', headerText: 'Category Name', width: 150 },
            { field: 'ProductName', headerText: 'Product Name', width: 150 }
        ],
        height: 315
});
grid.appendTo('#Grid');
<!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="https://cdn.syncfusion.com/ej2/28.1.33/ej2-base/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-buttons/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-popups/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-navigations/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-dropdowns/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-lists/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-inputs/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-calendars/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-splitbuttons/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-grids/styles/bootstrap5.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <script id="template" type="text/x-template">
            <div class="template_checkbox">
                ${if(Discontinued)}
                <input type="checkbox" checked> ${else}
                <input type="checkbox"> ${/if}
            </div>
        </script>
        <div id='Grid'></div>
    </div>
</body>

</html>

You can use any template element or custom control instead of the checkbox in the conditional template based on your requirement.

How to get the row object by clicking on the template element

The Grid control allows you to retrieve the row object of the selected record when clicking on a template element. This feature can be useful when you need to perform custom actions based on the selected record.

In the following code, the button element is rendered in the Employee Data column and click event binding is used to call the showDetails method when the template element is clicked. The showDetails method is passed the data object as an argument, which allows you to access the selected row object and display it in the dialog popup.

import { Grid, QueryCellInfoEventArgs } from '@syncfusion/ej2-grids';
import { employeeData } from './datasource.ts';
import { Dialog } from '@syncfusion/ej2-popups';

let grid: Grid = new Grid({
    dataSource: employeeData,
    queryCellInfo: queryCellInfo,
    columns: [
      { field: 'EmployeeID', headerText: 'Employee ID', textAlign:'Right', width: 130 },
      { field: 'FirstName', headerText: 'First Name', width: 120 },
      { field: 'Employee Data', headerText: 'Employee Data', textAlign:'Right', template: '#columnTemplate', width: 150, isPrimaryKey: true },
    ],
    height: 315,
});
grid.appendTo('#Grid');

function queryCellInfo(args: QueryCellInfoEventArgs) {
  if (args.column.headerText === 'Employee Data') {
    args.cell.querySelector('#button').addEventListener('click', (e) => {
      dialog.visible = true
      dialog.content =
        `<p><b>EmployeeID:</b> ${args.data.EmployeeID}</p>
         <p><b>FirstName:</b> ${args.data.FirstName}</p>
         <p><b>LastName:</b> ${args.data.LastName}</p>`
    })
  }
}

let dialogVisible = false;

let dialog: Dialog = new Dialog({
  header: "Selected Row Details",
  content: "dialogContent",
  showCloseIcon: true,
  width: "50%",
  visible: dialogVisible
})
dialog.appendTo('#dialog');
<!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="https://cdn.syncfusion.com/ej2/28.1.33/ej2-base/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-buttons/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-popups/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-navigations/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-dropdowns/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-lists/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-inputs/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-calendars/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-splitbuttons/styles/bootstrap5.css" rel="stylesheet" /> 
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-grids/styles/bootstrap5.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <script type="text/x-template" id="columnTemplate" >
            <button id='button' class='e-btn'>View</button>
        </script>
        <div id="dialog"></div>
        <div id="Grid"></div>           
    </div>
</body>
</html>

Use custom helper inside the template

The Syncfusion Grid allows you to use custom helpers inside the template property of a column. This feature allows you to create complex templates that can incorporate additional helper functions that are not available through the default template syntax.

To use the custom helper function inside a column template, you must first add the function to the template’s context.

The following example demonstrates how to use a custom helper function inside the template property, using the template element for the Freight column.

import { Grid } 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: 90 },
      { field: 'CustomerID', headerText: 'Customer ID', width: 120 },
      { field: 'Freight', headerText: 'Freight', template: '#template', textAlign: 'Right', format: 'C2', width: 90 },
      { field: 'OrderDate', headerText: 'Order Date', textAlign: 'Right', format:'yMd', width: 120 }
    ],
    height: 315,
});
grid.appendTo('#Grid');
<!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="https://cdn.syncfusion.com/ej2/28.1.33/ej2-base/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-buttons/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-popups/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-navigations/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-dropdowns/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-lists/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-inputs/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-calendars/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-splitbuttons/styles/bootstrap5.css" rel="stylesheet" /> 
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-grids/styles/bootstrap5.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <script type="text/x-template" id="template" >
            ${ formatCurrency(data.Freight) }
        </script>
        <script>
          function formatCurrency(value) {
            return '₹ ' + value.toFixed(3);
          }
        </script>
        <div id="Grid"></div>           
    </div>
</body>
</html>

Custom helpers can only be used inside the template property of a column.

Dynamically adding template column

The Syncfusion Grid control allows you to dynamically add template columns at runtime. This capability is particularly useful when the structure of the grid needs to be modified based on individual interactions or other dynamic conditions.

Dynamically adding template columns involves creating and inserting columns with custom templates after the grid has been initialized. This approach provides flexibility in presenting data in a highly customizable manner.

The following example demonstrates how to add template column using external button click. In this example, the ShipCountry column with a Dropdownlist is added in column template, and an icon is displayed using the headerTemplate for the ShipCountry column.

import { Grid, QueryCellInfoEventArgs } from '@syncfusion/ej2-grids';
import { data } from './datasource.ts';
import { Button } from '@syncfusion/ej2-buttons';
import { DropDownList } from '@syncfusion/ej2-dropdowns';

let dropData = ['USA', 'Germany', 'Brazil', 'France', 'Belgium','Switzerland','Venezuela','Austria', 'Mexico'];
let grid: Grid = new Grid({
  dataSource: data,
  height: 315,
  columns: [
      { field: 'OrderID', headerText: 'Order ID', width: 80 },
      { field: 'CustomerID', headerText: 'Customer Name', width: 100 },
      { field: 'Freight', headerText: 'Freight', width: 80 }
  ],
  queryCellInfo: function(args: QueryCellInfoEventArgs) {
      if (args.column.field === 'ShipCountry') {
          let dropDownList = new DropDownList({
              dataSource: dropData,
              fields: { text: 'ShipCountry', value: 'ShipCountry' },
              value: args.data['ShipCountry'],
              index:0
          });
          dropDownList.appendTo(args.cell.querySelector('#dropElement'));
      }
  }
});
grid.appendTo('#Grid');

let addButton: Button = new Button();
addButton.appendTo('#button');

(document.getElementById('button') as HTMLElement).onclick = function () {
  let newColumn = {
    field: 'ShipCountry',
    headerText: 'Ship Country',
    width: 100,
    headerTemplate: '#headerTemplate',
    template: '#columnTemplate'
};
grid.columns.push(newColumn);
grid.refreshColumns();
};
<!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="https://cdn.syncfusion.com/ej2/28.1.33/ej2-base/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-buttons/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-popups/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-navigations/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-dropdowns/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-lists/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-inputs/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-calendars/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-splitbuttons/styles/bootstrap5.css" rel="stylesheet" /> 
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-grids/styles/bootstrap5.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
      <script id="columnTemplate" type="text/x-template">
        <input id="dropElement" type="text" />
    </script>
    <script id="headerTemplate" type="text/x-template">
        <div><span class="e-icons e-location"></span> Ship Country</div>
    </script>
    <button id="button" class="e-outline">Add Column</button>
        <div id="Grid"></div>           
    </div>
</body>
</html>