Row template in EJ2 TypeScript Grid control

21 Feb 202524 minutes to read

The row template feature in Grid allows you to customize the appearance and layout of rows in the grid. This feature is useful when you want to display custom content, such as images, buttons, or other controls, within the rows.

To enable the row template feature, you need to set the rowTemplate property of the Grid control. This property accepts a custom HTML template that defines the layout for each row.

In the following example, Employee Information with Employee Photo is presented in the first column and employee details like Name, Address, etc., are presented in the second column.

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

let grid: Grid = new Grid({
    dataSource: employeeData,
    rowTemplate: '#rowtemplate',
    columns: [
        { headerText: 'Employee Image', width: 150, textAlign: 'Center', field: 'OrderID' },
        { headerText: 'Employee Details', width: 300, field: 'EmployeeID' }
    ],
    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/29.1.33/ej2-base/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-grids/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-buttons/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-popups/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-navigations/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-dropdowns/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-lists/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-inputs/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-calendars/styles/bootstrap5.css" rel="stylesheet" /> 
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-splitbuttons/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>
   <script id="rowtemplate" type="text/x-template">
    <tr>
        <td class="photo">
            <img src="${EmployeeID}.png" alt="${EmployeeID}" />
        </td>
        <td class="details">
            <table class="CardTable" cellpadding="3" cellspacing="2">
                <colgroup>
                    <col width="50%">
                    <col width="50%">
                </colgroup>
                <tbody>
                    <tr>
                        <td class="CardHeader">First Name </td>
                        <td>${FirstName} </td>
                    </tr>
                    <tr>
                        <td class="CardHeader">Last Name</td>
                        <td>${LastName} </td>
                    </tr>
                    <tr>
                        <td class="CardHeader">Title
                        </td>

                        <td>${Title}
                        </td>
                    </tr>
                </tbody>
            </table>
        </td>
     </tr>
    </script>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Grid'></div>
    </div>
</body>
</html>

Row template with formatting

The row template feature in Syncfusion Grid allows you to customize the layout of rows in the grid. This is useful when you want to display images, buttons, or other custom content within the rows of a grid.

By default, Syncfusion Grid provides the columns->format property to format the values displayed in each column. However, when using the rowtemplate, the columns->format property cannot be directly applied to format the values inside the template.

To format the values within the row template, you can define a global function that handles the formatting logic. This function can be invoked inside the template to format the corresponding values.

Here is an example of how to define a global formatting function for a date column and use it inside a rowTemplate:

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

let intl: Internationalization = new Internationalization();

let dFormatter: Function = intl.getDateFormat({ skeleton: 'yMd', type: 'date' });

(<IWindow>window).formatDate = (date: Date) => dFormatter(date);

let grid: Grid = new Grid({
    dataSource: employeeData,
    rowTemplate: '#rowtemplate',
    columns: [
        { headerText: 'Employee Image', width: 150, textAlign: 'Center', field: 'OrderID' },
        { headerText: 'Employee Details', width: 300, field: 'EmployeeID' }
    ],
    height: 315
});
grid.appendTo('#Grid');

interface IWindow extends Window {
    formatDate?: Function;
}
<!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/29.1.33/ej2-base/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-grids/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-buttons/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-popups/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-navigations/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-dropdowns/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-lists/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-inputs/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-calendars/styles/bootstrap5.css" rel="stylesheet" />   
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-splitbuttons/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>
   <script id="rowtemplate" type="text/x-template">
    <tr>
        <td class="photo">
            <img src="${EmployeeID}.png" alt="${EmployeeID}" />
        </td>
        <td class="details">
            <table class="CardTable" cellpadding="3" cellspacing="2">
                <colgroup>
                    <col width="50%">
                    <col width="50%">
                </colgroup>
                <tbody>
                    <tr>
                        <td class="CardHeader">First Name </td>
                        <td>${FirstName} </td>
                    </tr>
                    <tr>
                        <td class="CardHeader">Last Name</td>
                        <td>${LastName} </td>
                    </tr>
                    <tr>
                        <td class="CardHeader">Title
                        </td>

                        <td>${Title}
                        </td>
                    </tr>
                    <tr>
                        <td class="CardHeader">Birth Date
                        </td>
                        <td>${formatDate(data.BirthDate)}
                        </td>
                    </tr>
                    <tr>
                        <td class="CardHeader">Hire Date
                        </td>
                        <td>${formatDate(data.HireDate)}
                        </td>
                    </tr>
                </tbody>
            </table>
        </td>
     </tr>
    </script>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Grid'></div>        
    </div>
</body>
</html>

When using the rowTemplate feature in Syncfusion Grid, keep in mind that any formatting applied to columns using the columns->format property will not work inside the template.

Render syncfusion control in row template

The Grid allows you to render custom Syncfusion controls within the rows of the grid. This feature is helpful as it enables you to display interactive Syncfusion controls instead of field values in the grid.

To enable a Syncfusion control in a row template, you need to set the rowTemplate property of the Grid control. This property accepts a custom HTML template that defines the layout for each row.

Here is an example that demonstrates rendering Syncfusion controls within a row template :

import { Grid } from '@syncfusion/ej2-grids';
import { data } from './datasource.ts';
import { ChipList } from '@syncfusion/ej2-buttons';
import { NumericTextBox } from '@syncfusion/ej2-inputs';
import { DatePicker } from '@syncfusion/ej2-calendars';
import { DropDownList } from '@syncfusion/ej2-dropdowns';

let grid: Grid = new Grid({
    dataSource: data,
    rowTemplate: '#rowtemplate',
    columns: [
        { field: 'OrderID', headerText: 'Order ID', width: 120 },
        { field: 'Quantity', headerText: 'Quantity', width: 170 },
        { field: 'ShipAddress', headerText: 'Ship Address', width: 170 },
        { field: 'OrderDate', headerText: 'Order Date', width: 120 },
        { field: 'OrderStatus', headerText: 'Order Status', width: 120 },
    ],
    dataBound: () => {

        let gridInstance = (document.getElementById('Grid') as Grid).ej2_instances[0];

        let chipList = gridInstance.getContentTable().querySelectorAll('.chipList');
        for (let i = 0; i < chipList.length; i++) {
            let chipValue  = chipList[i].innerText;
            new ChipList({ chips: [chipValue] }, chipList[i]);
        }

        let NumericList = gridInstance.getContentTable().querySelectorAll('.numeric');
        for (let i = 0; i < NumericList.length; i++) {
            let numeric: NumericTextBox = new NumericTextBox({});
            numeric.appendTo(NumericList[i]);
        }

        let dateList = gridInstance.getContentTable().querySelectorAll('.date-input');
        for (let i = 0; i < dateList.length; i++) {
            let dateInput = dateList[i];
            let dateValue = dateInput.value;
            let datepickerObject: DatePicker = new DatePicker({
                value: new Date(dateValue),
            });
            datepickerObject.appendTo(dateInput);
        }
        
        let dropdownList = gridInstance.getContentTable().querySelectorAll('.dropdownlist-input');
        for (let i = 0; i < dropdownList.length; i++) {
            let dropdownInputValue = dropdownList[i];
            let dropData = ['Processing', 'Order Placed', 'Delivered'];
            let dropdown:DropDownList = new DropDownList({
                dataSource: dropData,
                value: dropdownList[i].value,
                popupHeight: 150,
                popupWidth: 150
            });
            dropdown.appendTo(dropdownInputValue);
        }
    },
});
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/29.1.33/ej2-base/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-grids/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-buttons/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-popups/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-navigations/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-dropdowns/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-lists/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-inputs/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-calendars/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-splitbuttons/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>
   <script id="rowtemplate" type="text/x-template">
    <tr class="rows">
        <td class="chipList"> ${OrderID}</td>
        <td><input class="numeric" type="text" value=${Quantity}></td>
        <td>${ShipAddress} </td>
        <td><input class="date-input" value="${OrderDate}"></td>
        <td><input class="dropdownlist-input" type="text" value="${OrderStatus}"></td>
     </tr>
    </script>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Grid'></div>
    </div>
</body>
</html>

Render Syncfusion Chart in row template

The Syncfusion Grid component provides the flexibility to include custom controls, such as Chart, within the rows of the Grid. This feature enhances Grid interactivity by allowing you to display graphical representations of data instead of plain text.

To render a Syncfusion Chart within a row template of the Grid, you can utilize the rowTemplate property. This property accepts a custom HTML template that specifies the layout for each row, allowing for rich data visualization.

Here is an example that demonstrates rendering Syncfusion Chart within a row template:

import { Grid } from '@syncfusion/ej2-grids';
import { employeeData, employeePerformanceData } from './datasource.ts';
import { Chart, ColumnSeries, Category } from '@syncfusion/ej2-charts';

Chart.Inject(ColumnSeries, Category);

let grid: Grid = new Grid({
    dataSource: employeeData,
    rowTemplate: '#rowtemplate',
    columns: [
        { field: 'Name', headerText: "Employee Name", width: 150 },
        { field: 'Designation', headerText: "Designation", width: 150 },
        { field: 'Team', headerText: "Team", width: 150 },
        { headerText: 'Employee Performance', width: 300, textAlign: "Center" }
    ],
    dataBound: dataBound,
    height: 400
});
grid.appendTo('#Grid');

function dataBound() {
    let gridInstance = (document.getElementById('Grid') as any).ej2_instances[0];
    let chartList = gridInstance.getContentTable().querySelectorAll('.chart-container');
    for (let i = 0; i < chartList.length; i++) {
         let chartData=getChartData((employeeData[i] as any).EmployeeID);
        let chartComponent: Chart = new Chart({
            height:"150",
            primaryXAxis: { valueType: 'Category' },
            series: [{
                dataSource:chartData
                type: "Column",
                xName: "month",
                yName: "performance",
                name: "Performance"
            }],
        });
        chartComponent.appendTo(chartList[i]);
    }
}
function getChartData(employeeID: number) {
    const employeePerformance = employeePerformanceData.find(emp => (emp as any).EmployeeID === employeeID);
    return employeePerformance ? (employeePerformance as any).chartData : [];
}
<!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/29.1.33/ej2-base/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-grids/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-buttons/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-popups/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-navigations/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-dropdowns/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-lists/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-inputs/styles/bootstrap5.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-calendars/styles/bootstrap5.css" rel="stylesheet" /> 
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-splitbuttons/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>
    <style>
.custom,
.details {
    border-color: #e0e0e0;
    border-style: solid;
}

.custom {
    border-width: 1px 0px 0px 0px;
}

.details {
    border-width: 1px 0px 0px 0px;
}

.details > table {
    width: 100%;
}

td {
    padding: 5px 8px; /* Better padding for readability */
    font-size: 14px;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
   <script id="rowtemplate" type="text/x-template">
    <tr>
        <td class="custom">
            <div>
            ${Name}
            </div>
        </td>
        <td class="custom">
            <div>
            ${Designation}
            </div>
        </td>
        <td class="custom">
            <div>
           ${Team}
            </div>
        </td>
        <td class="details">
            <div class='chart-container'></div>
        </td>
     </tr>
    </script>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Grid'></div>
    </div>
</body>
</html>

Limitations

Row template feature is not compatible with all the features which are available in the grid, and it has limited features support. The features that are incompatible with the row template feature are listed below.

  • Filtering
  • Paging
  • Sorting
  • Searching
  • Rtl
  • Export
  • Context Menu
  • State Persistence
  • Selection
  • Grouping
  • Editing
  • Frozen rows & columns
  • Virtual & Infinite scrolling
  • Column chooser
  • Column menu
  • Detail Row
  • Foreignkey column
  • Resizing
  • Reordering
  • Aggregates
  • Clipboard
  • Adaptive view