Editing in Angular Data Grid
5 Sep 202624 minutes to read
The Angular Data Grid component includes built-in editing features for creating, reading, updating, and deleting data directly in the grid. This eliminates the need for separate forms and allows data modification within a single interface. The grid editing provides powerful options through multiple edit modes such as inline editing, dialog editing, batch editing, custom editors, validation, CRUD operations, and template-based editing.
Set up editing
Before using editing in the grid, understand that the component needs the EditService module to unlock all editing features. The EditService is a service that powers all create, read, update, and delete operations. Without it, editing features cannot work.
Inject the EditService to the providers array.
import { Component, OnInit } from '@angular/core';
import { GridComponent, EditService, ToolbarService, PageService, SortService } from '@syncfusion/ej2-angular-grids';
@Component({
selector: 'app-root',
providers: [EditService, ToolbarService, PageService, SortService]
template: `
<ejs-grid [dataSource]='data'>
</ejs-grid>`,
})
export class AppComponent {
public data: any[] = [...];
}Enable editing
To enable editing functionality directly within the grid, configure the allowEditing, allowAdding, and allowDeleting properties within the editSettings to true.
| Property | Purpose |
|---|---|
allowEditing |
Enable editing of existing records |
allowAdding |
Enable adding new records |
allowDeleting |
Enable deleting records |
Editing requires a primary key column to support full CRUD functionality. Define the primary key by setting columns.isPrimaryKey to true on the relevant column.
Edit actions can be initiated by double-clicking a row or by selecting a row and clicking the Edit button in the toolbar. Records can be added by clicking the Add button in the toolbar or via an external trigger that invokes the addRecord method. Use Save and Cancel to commit or discard changes from the toolbar during edit mode. Deletion is performed by selecting the target row and clicking the Delete button.
To explore available edit modes and types in Data Grid, refer to the following video:
The following example demonstrates enabling editing in the grid:
import { data } from './datasource';
import { Component, OnInit } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { DatePickerAllModule, TimePickerModule } from '@syncfusion/ej2-angular-calendars';
import { AutoCompleteModule, DropDownListModule, MultiSelectModule } from '@syncfusion/ej2-angular-dropdowns';
import { EditService, EditSettingsModel, GridModule, PageService, SortService, ToolbarItems, ToolbarService } from '@syncfusion/ej2-angular-grids';
import { TextBoxModule } from '@syncfusion/ej2-angular-inputs';
@Component({
imports: [
GridModule,
DatePickerAllModule,
FormsModule,
TimePickerModule,
FormsModule,
TextBoxModule,
MultiSelectModule,
AutoCompleteModule
],
providers: [EditService, ToolbarService, SortService, PageService],
standalone: true,
selector: 'app-root',
template: `<ejs-grid [dataSource]='data' [editSettings]='editSettings' height='273px'>
<e-columns>
<e-column field='OrderID' headerText='Order ID' textAlign='Right' [validationRules]='orderIDRules'
isPrimaryKey='true' width=100></e-column>
<e-column field='CustomerID' headerText='Customer ID' [validationRules]='customerIDRules' width=120></e-column>
<e-column field='Freight' headerText='Freight' textAlign= 'Right' editType= 'numericedit'
width=120 [validationRules]='freightRules' format= 'C2'></e-column>
<e-column field='ShipCountry' headerText='Ship Country' editType= 'dropdownedit' width=150></e-column>
</e-columns>
</ejs-grid>`
})
export class AppComponent implements OnInit {
public data?: object[];
public editSettings?: EditSettingsModel;
public toolbar?: ToolbarItems[];
public orderIDRules?: Object;
public customerIDRules?: Object;
public freightRules?: Object;
ngOnInit(): void {
this.data = data;
this.orderIDRules = { required: true, number: true };
this.customerIDRules = { required: true };
this.freightRules = { required: true,min:1, max:1000 };
this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, };
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
- If columns.isIdentity is enabled, the column will be treated as read-only when editing or adding records.
- Use
columns.allowEditingset tofalseto disable editing for specific columns.- The
Insertkey adds a new row, and theDeletekey deletes the selected row in the grid.
Edit modes
The Data Grid supports multiple editing options to meet different data-editing requirements:
- Inline edit: Allows direct modification of row or cell values within the grid.
- Batch edit: Enables editing and saving of multiple cells in a single action.
- Cell edit: Allows to edit individual cell values directly within the grid.
- Dialog edit: Opens a dedicated modal dialog window to edit row data.
Use the editSettings.mode property to specify the desired edit mode.
Edit records using the toolbar
The toolbar with edit option feature provides a built-in toolbar that includes items for editing actions. Using the toolbar, grid records can be modified, updated, or canceled during edit operations.
Configure the toolbar property of the Grid component to enable this feature. The toolbar property defines the items displayed in the grid toolbar. Include relevant items like Edit, Add, Delete, Update, and Cancel within the toolbar property to enable edit options in the toolbar.
The following example demonstrates how to enable the toolbar with edit option in the grid:
import { data } from './datasource';
import { Component, OnInit } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { DatePickerAllModule, TimePickerModule } from '@syncfusion/ej2-angular-calendars';
import { AutoCompleteModule, MultiSelectModule } from '@syncfusion/ej2-angular-dropdowns';
import { EditService, EditSettingsModel, GridModule, PageService, SortService, ToolbarItems, ToolbarService } from '@syncfusion/ej2-angular-grids';
import { TextBoxModule } from '@syncfusion/ej2-angular-inputs';
@Component({
imports: [
GridModule,
DatePickerAllModule,
FormsModule,
TimePickerModule,
FormsModule,
TextBoxModule,
MultiSelectModule,
AutoCompleteModule
],
providers: [EditService, ToolbarService, SortService, PageService],
standalone: true,
selector: 'app-root',
template: `<ejs-grid [dataSource]='data' [editSettings]='editSettings' [toolbar]='toolbar' height='273px'>
<e-columns>
<e-column field='OrderID' headerText='Order ID' [validationRules]='orderIDRules' textAlign='Right' isPrimaryKey='true' width=100></e-column>
<e-column field='CustomerID' headerText='Customer ID' [validationRules]='customerIDRules' width=120></e-column>
<e-column field='Freight' headerText='Freight' [validationRules]='freightRules' textAlign= 'Right' width=120 format= 'C2'></e-column>
<e-column field='ShipCountry' headerText='Ship Country' [validationRules]='shipCountryRules' width=150></e-column>
</e-columns>
</ejs-grid>`
})
export class AppComponent implements OnInit {
public data?: object[];
public editSettings?: EditSettingsModel;
public toolbar?: ToolbarItems[];
public orderIDRules?: Object;
public customerIDRules?: Object;
public freightRules?: Object;
public shipCountryRules?: Object;
ngOnInit(): void {
this.data = data;
this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true };
this.toolbar = ['Add', 'Edit', 'Delete', 'Update', 'Cancel'];
this.orderIDRules = { required: true, number: true };
this.customerIDRules = { required: true };
this.freightRules = {required: true ,number: true };
this.shipCountryRules = { required: true };
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Column validation
Column validation applies validation rules to individual columns during edit operations, ensuring data accuracy before saving. Invalid data displays error messages and prevents saving. The FormValidator component validates data using rules defined in the validationRules property for each column.
Example of applying validation rules to a grid column:
import { data } from './datasource';
import { Component, OnInit } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { DatePickerAllModule, TimePickerModule } from '@syncfusion/ej2-angular-calendars';
import { AutoCompleteModule, DropDownListModule, MultiSelectModule } from '@syncfusion/ej2-angular-dropdowns';
import { EditService, EditSettingsModel, GridModule, PageService, SortService, ToolbarItems, ToolbarService } from '@syncfusion/ej2-angular-grids';
import { TextBoxModule } from '@syncfusion/ej2-angular-inputs';
@Component({
imports: [
GridModule,
DatePickerAllModule,
FormsModule,
TimePickerModule,
FormsModule,
TextBoxModule,
MultiSelectModule,
AutoCompleteModule,
DropDownListModule
],
providers: [EditService, ToolbarService, SortService, PageService],
standalone: true,
selector: 'app-root',
template: `
<ejs-grid [dataSource]='data' [editSettings]='editSettings' [toolbar]='toolbar' height='273'>
<e-columns>
<e-column field='OrderID' headerText='Order ID' textAlign='Right' isPrimaryKey='true' [validationRules]='orderIDRules' width=100></e-column>
<e-column field='CustomerID' headerText='Customer ID' [validationRules]='customerIDRules' width=120></e-column>
<e-column field='Freight' [validationRules]='freightRules' headerText='Freight' textAlign= 'Right' editType= 'numericedit' width=120 format= 'C2'></e-column>
<e-column field='ShipCountry' headerText='Ship Country' editType= 'dropdownedit' width=150></e-column>
</e-columns>
</ejs-grid>`
})
export class AppComponent implements OnInit {
public data?: object[];
public editSettings?: EditSettingsModel;
public toolbar?: ToolbarItems[];
public orderIDRules?: object;
public customerIDRules?: object;
public freightRules?: Object;
ngOnInit(): void {
this.data = data;
this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Normal' };
this.toolbar = ['Add', 'Edit', 'Delete', 'Update', 'Cancel'];
this.orderIDRules = { required: true };
this.customerIDRules = { required: true, minLength: 3 };
this.freightRules = { required: true, min: 1, max: 1000 };
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Disable editing for specific columns
The Data Grid provides the option to disable editing for specific columns. This is useful when certain columns should remain read-only, such as columns containing calculated values, IDs, or system-generated data.
Static column disabling
To permanently disable editing for a column, set the allowEditing property to false on the column. This prevents editing for that column across all rows:
<e-column field='OrderID' [allowEditing]='false'></e-column>Dynamic column disabling
To disable editing for a column based on application interaction or conditions, use the allowEditing property of the columns object. Set this property to false to prevent editing for that specific column.
The following example demonstrates how to disable editing for selected columns dynamically in the grid.
import { data } from './datasource';
import { Component, ViewChild } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { DatePickerAllModule, TimePickerModule } from '@syncfusion/ej2-angular-calendars';
import { AutoCompleteModule, DropDownListComponent, DropDownListModule, MultiSelectModule } from '@syncfusion/ej2-angular-dropdowns';
import { Column, EditService, GridComponent, GridModule, PageService, SortService, ToolbarService } from '@syncfusion/ej2-angular-grids';
import { TextBoxModule } from '@syncfusion/ej2-angular-inputs';
import { ChangeEventArgs } from '@syncfusion/ej2-dropdowns';
@Component({
imports: [
GridModule,
DatePickerAllModule,
FormsModule,
TimePickerModule,
FormsModule,
TextBoxModule,
MultiSelectModule,
AutoCompleteModule,
DropDownListModule
],
providers: [EditService, ToolbarService, SortService, PageService],
standalone: true,
selector: 'app-root',
templateUrl: './app.component.html',
})
export class AppComponent {
public data?: Object[];
@ViewChild('grid') public grid?: GridComponent;
@ViewChild('dropdown') public dropdown?: DropDownListComponent;
public editSettings?: Object;
public toolbar?: string[];
public orderIDRules?: Object;
public customerIDRules?: Object;
public freightRules?: Object;
public editparams?: Object;
public pageSettings?: Object;
public alignmentData: Object[] = [
{ text: 'Order ID', value: 'OrderID' },
{ text: 'Customer ID', value: 'CustomerID' },
{ text: 'Freight', value: 'Freight' },
{ text: 'Order Date', value: 'OrderDate' },
{ text: 'Ship Country', value: 'ShipCountry' },
];
public dropdownFields: Object = { text: 'text', value: 'value' }; // Define fields for the dropdown
public currentColumn?: Column;
public ngOnInit(): void {
this.data = data;
this.editSettings = {
allowEditing: true,
allowAdding: true,
allowDeleting: true,
};
this.toolbar = ['Add', 'Delete', 'Update', 'Cancel'];
this.orderIDRules = { required: true, number: true };
this.customerIDRules = { required: true };
this.freightRules = { required: true };
this.editparams = { params: { popupHeight: '300px' } };
this.pageSettings = { pageCount: 5 };
}
public changeAlignment(args: ChangeEventArgs): void {
// Reset the allowEditing property of the previously selected column
if (this.currentColumn) {
this.currentColumn.allowEditing = true;
}
// Update the 'allowEditing' property for the selected column
this.currentColumn = this.grid?.getColumnByField((args.value as string)) as Column;
this.currentColumn.allowEditing = false;
}
}<div style="display: flex">
<label style="padding: 30px 17px 0 0;"> Select column to disable editing:</label>
<ejs-dropdownlist #dropdown style="padding: 26px 0 0 0" index="0" width="150"
[dataSource]="alignmentData" [fields]="dropdownFields" (change)="changeAlignment($event)">
</ejs-dropdownlist>
</div>
<div>
<ejs-grid #grid id='Batchgrid' [dataSource]='data' allowPaging='true' [pageSettings]='pageSettings'
[editSettings]='editSettings' [toolbar]='toolbar' height='180px'>
<e-columns>
<e-column field='OrderID' headerText='Order ID' width='120' textAlign='Right' isPrimaryKey='true'
[validationRules]='orderIDRules'></e-column>
<e-column field='CustomerID' headerText='Customer ID' width='120' [validationRules]='customerIDRules'
></e-column>
<e-column field='Freight' headerText='Freight' width='120' format='C2' textAlign='Right'
editType='numericedit' [validationRules]='freightRules' >
</e-column>
<e-column field='OrderDate' headerText='Order Date' width='130' format='yMd' editType='datepickeredit'
textAlign='Right' ></e-column>
<e-column field='ShipCountry' headerText='Ship Country' width='150' editType='dropdownedit'
[edit]='editparams' ></e-column>
</e-columns>
</ejs-grid>
</div>import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
- If isPrimaryKey is enabled, editing is automatically disabled for that column.
- To disable editing for a specific row using the actionBegin event. See example here.
- To disable editing for a particular cell using the cellEdit event. See example here.
Customize column editors using templates
Customizing the editing experience for specific columns is possible by defining an editing template. Use the field property to connect the column with its corresponding data field.
In this example, the “Ship Country” column is rendered with a template:
import { FormsModule } from '@angular/forms';
import { GridModule, EditService, ToolbarService, SortService, PageService } from '@syncfusion/ej2-angular-grids';
import { DatePickerAllModule, TimePickerModule } from '@syncfusion/ej2-angular-calendars';
import { DropDownListModule, MultiSelectModule, AutoCompleteModule };
import { TextBoxModule } from '@syncfusion/ej2-angular-inputs';
import { Component, OnInit } from '@angular/core';
import { data } from './datasource';
import { EditSettingsModel, ToolbarItems } from '@syncfusion/ej2-angular-grids';
@Component({
imports: [
GridModule,
DatePickerAllModule,
FormsModule,
TimePickerModule,
TextBoxModule,
MultiSelectModule,
AutoCompleteModule
],
providers: [EditService, ToolbarService, SortService, PageService],
standalone: true,
selector: 'app-root',
template: `<ejs-grid [dataSource]='data' [editSettings]='editSettings' [toolbar]='toolbar' height='273px'>
<e-columns>
<e-column field='OrderID' headerText='Order ID' [validationRules]='orderIDRules' textAlign='Right' isPrimaryKey='true' width=100></e-column>
<e-column field='CustomerID' [validationRules]='customerIDRules' headerText='Customer ID' width=120></e-column>
<e-column field='Freight' headerText='Freight' textAlign= 'Right'
editType= 'numericedit' width=120 [validationRules]='freightRules' format= 'C2'></e-column>
<e-column field='ShipCountry' headerText='Ship Country' editType= 'dropdownedit' width=150>
<ng-template #template let-data>
<a href="#" aria-label="View ship country">{{data.ShipCountry}}</a>
</ng-template>
</e-column>
</e-columns>
</ejs-grid>`
})
export class AppComponent implements OnInit {
public data?: object[];
public editSettings?: EditSettingsModel;
public toolbar?: ToolbarItems[];
public orderIDRules?: object;
public customerIDRules?: object;
public freightRules?: Object;
ngOnInit(): void {
this.data = data;
this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true };
this.toolbar = ['Add', 'Edit', 'Delete', 'Update', 'Cancel'];
this.orderIDRules = { required: true };
this.freightRules = { min:1, max:1000 };
this.customerIDRules = { required: true };
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Edit enum columns
Enum columns contain predefined list values (enumerated data). Instead of allowing free-form text input, using a dropdown editor ensures data consistency and prevents invalid entries. The editTemplate property enables custom editors for enum data.
The following example demonstrates how to render a DropDownList component as an edit template for the “Employee Feedback” column, binding it to a predefined list of enum values:
import { data } from './datasource';
import { Component, OnInit } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { DatePickerAllModule, TimePickerModule } from '@syncfusion/ej2-angular-calendars';
import { AutoCompleteModule, ComboBoxModule, DropDownListModule, MultiSelectModule } from '@syncfusion/ej2-angular-dropdowns';
import { EditService, EditSettingsModel, ForeignKeyService, GridModule, PageService, SaveEventArgs, SortService, ToolbarItems, ToolbarService } from '@syncfusion/ej2-angular-grids';
import { TextBoxModule } from '@syncfusion/ej2-angular-inputs';
@Component({
imports: [
GridModule,
DatePickerAllModule,
FormsModule,
TimePickerModule,
FormsModule,
TextBoxModule,
MultiSelectModule,
AutoCompleteModule,
DropDownListModule,
ComboBoxModule
],
providers: [EditService, ToolbarService, SortService, ForeignKeyService,PageService],
standalone: true,
selector: 'app-root',
template: `<ejs-grid [dataSource]="details" [editSettings]="editSettings" [toolbar]="toolbar" (actionBegin)="actionBegin($event)" height='250px'>
<e-columns>
<e-column field="OrderID" headerText="Order ID" isPrimaryKey="true" textAlign="Right" width="90"></e-column>
<e-column field="CustomerID" headerText="Employee Name" textAlign="Left" width="100"></e-column>
<e-column field="FeedbackDetails" headerText="Employee Feedback" textAlign="Left" width="120">
<ng-template #editTemplate let-data>
<ejs-dropdownlist [(ngModel)]="orderData.FeedbackDetails" [dataSource]="dropDownEnumValue" [fields]="dropdownFields" popupHeight="150px">
</ejs-dropdownlist>
</ng-template>
</e-column>
</e-columns>
</ejs-grid>`
})
export class AppComponent implements OnInit {
public details?: EmployeeDetails[];
public editSettings?: EditSettingsModel;
public toolbar?: ToolbarItems[];
public orderData?: EmployeeDetails | any;
public orderIDRules?: object;
public customerIDRules?: object;
public freightRules?: object;
public dropDownEnumValue: string[] = [];
public dropdownFields: Object = { text: 'FeedbackDetails', value: 'FeedbackDetails' };
ngOnInit(): void {
this.details = data as EmployeeDetails[];
this.orderIDRules = { required: true };
this.freightRules = { required: true, min: 1, max: 1000 };
this.editSettings = {
allowEditing: true,
allowAdding: true,
allowDeleting: true,
};
this.toolbar = ['Add', 'Edit', 'Delete', 'Update', 'Cancel'];
this.dropDownEnumValue = Object.keys(Feedback).filter((key: string) => !isNaN(Number((Feedback as any)[key])));
}
actionBegin(args: SaveEventArgs) {
if (args.requestType === 'beginEdit' || args.requestType === 'add') {
this.orderData = Object.assign({}, args.rowData);
}
if (args.requestType === 'save') {
(args.data as EmployeeDetails)['FeedbackDetails'] = this.orderData['FeedbackDetails'];
}
}
}
export interface EmployeeDetails {
OrderID: number;
CustomerID: string;
FeedbackDetails: Feedback;
}
export enum Feedback {
Positive = 0,
Negative = 1,
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Edit complex columns
Complex columns contain nested data objects (such as “Name.FirstName”). When editing complex data with custom input elements, the binding syntax differs from simple columns. Use the underscore operator (___) instead of the dot operator (.) to correctly bind nested properties in edit templates.
The following example demonstrates how to edit complex nested data. The “FirstName” and “LastName” properties (nested under “Name”) are edited using input elements with names defined as “Name__FirstName” and “Name__LastName”:
import { complexData } from './datasource';
import { Component, OnInit } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { DatePickerAllModule, TimePickerModule } from '@syncfusion/ej2-angular-calendars';
import { AutoCompleteModule, DropDownListModule, MultiSelectModule } from '@syncfusion/ej2-angular-dropdowns';
import { EditService, EditSettingsModel, GridModule, PageService, SortService, ToolbarItems, ToolbarService } from '@syncfusion/ej2-angular-grids';
import { TextBoxModule } from '@syncfusion/ej2-angular-inputs';
@Component({
imports: [
GridModule,
DatePickerAllModule,
FormsModule,
TimePickerModule,
FormsModule,
TextBoxModule,
MultiSelectModule,
AutoCompleteModule,
DropDownListModule
],
providers: [EditService, ToolbarService, SortService, PageService],
standalone: true,
selector: 'app-root',
template: `
<ejs-grid #grid [dataSource]="data" height="295px" [editSettings]="editSettings" [toolbar]="toolbar" >
<e-columns>
<e-column field="EmployeeID" headerText="Employee ID" textAlign="Right" width="120"></e-column>
<e-column field="Name.FirstName" headerText="First Name" width="200">
<ng-template #editTemplate let-data>
<input class="e-input" name="Name___FirstName" type="text" id="Name___FirstName" [value]="data.Name.FirstName" />
</ng-template>
</e-column>
<e-column field="Name.LastName" headerText="Last Name" width="200">
<ng-template #editTemplate let-data>
<input class="e-input" type="text" name="Name___LastName" id="Name___LastName" [value]="data.Name.LastName" >
</ng-template>
</e-column>
<e-column field="Title" headerText="Title" width="150" ></e-column>
</e-columns>
</ejs-grid>
`,
})
export class AppComponent implements OnInit {
public data?: object[];
public editSettings?: EditSettingsModel;
public toolbar?: ToolbarItems[];
ngOnInit(): void {
this.data = complexData;
this.editSettings = {
allowEditing: true,
allowAdding: true,
allowDeleting: true,
};
this.toolbar = ['Add', 'Edit', 'Delete', 'Update', 'Cancel'];
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Edit foreign key columns
The Data Grid provides a powerful editing feature for foreign key columns by rendering a DropDownList component as the default editor during editing. This default editor can be replaced by defining the editTemplate property for the column using ng-template. The editTemplate property accepts either a template string or an HTML element ID and serves as the editor for a particular column.
In the following code example, the “Employee Name” is a foreign key column. When editing, the ComboBox component is rendered instead of DropDownList.
import { columnDataType, data, employeeData } from './datasource';
import { Component, OnInit } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { DatePickerAllModule, TimePickerModule } from '@syncfusion/ej2-angular-calendars';
import { AutoCompleteModule, ComboBoxModule, DropDownListModule, MultiSelectModule } from '@syncfusion/ej2-angular-dropdowns';
import { EditService, ForeignKeyService, GridModule, PageService, SortService, ToolbarService, EditSettingsModel,ToolbarItems,SaveEventArgs } from '@syncfusion/ej2-angular-grids';
import { TextBoxModule } from '@syncfusion/ej2-angular-inputs';
@Component({
imports: [
GridModule,
DatePickerAllModule,
FormsModule,
TimePickerModule,
FormsModule,
TextBoxModule,
MultiSelectModule,
AutoCompleteModule,
DropDownListModule,
ComboBoxModule
],
providers: [EditService, ToolbarService, SortService, ForeignKeyService,PageService],
standalone: true,
selector: 'app-root',
template: `
<ejs-grid [dataSource]="data" height="220" [editSettings]="editSettings" [allowPaging]="true" [toolbar]="toolbar" (actionBegin)=" actionBegin($event)">
<e-columns>
<e-column field="OrderID" headerText="Order ID" textAlign="Right" isPrimaryKey="true" width="120"></e-column>
<e-column field="EmployeeID" headerText="Employee Name" foreignKeyValue='FirstName' [dataSource]="employeeData" width="150">
<ng-template #editTemplate let-data>
<ejs-combobox [(value)]="orderData.EmployeeID" [dataSource]="employees" [fields]="comboFields" >
</ejs-combobox>
</ng-template>
</e-column>
<e-column field="OrderDate" headerText="Order Date" format="yMd" type="date" textAlign="Right" width="130"></e-column>
<e-column field="Freight" headerText="Freight" format="C2" textAlign="Right" width="120"></e-column>
</e-columns>
</ejs-grid>`
})
export class AppComponent implements OnInit {
public data?: object[];
public editSettings?: EditSettingsModel;
public toolbar?: ToolbarItems[];
public orderData?: object | any;
public orderIDRules?: object;
public customerIDRules?: object;
public employeeIDRules?: object;
public employees: object[] = [];
public employeeData: Object[] = employeeData;
public comboFields: Object = { text: 'FirstName', value: 'EmployeeID' };
ngOnInit(): void {
this.data = data;
this.orderIDRules = { required: true };
this.customerIDRules = { required: true };
this.employeeIDRules = { required: true };
this.editSettings = {
allowEditing: true,
allowAdding: true,
allowDeleting: true,
};
this.toolbar = ['Add', 'Edit', 'Delete', 'Update', 'Cancel'];
this.employees = [
{ FirstName: 'Nancy', EmployeeID: 1 },
{ FirstName: 'Andrew', EmployeeID: 6 },
{ FirstName: 'Janet', EmployeeID: 3 },
{ FirstName: 'Margaret', EmployeeID: 4 },
{ FirstName: 'Steven', EmployeeID: 5 },
{ FirstName: 'Laura', EmployeeID: 8 }
];
}
actionBegin(args: SaveEventArgs) {
if (args.requestType === 'beginEdit' || args.requestType === 'add') {
this.orderData = Object.assign({}, args.rowData);
}
if (args.requestType === 'save') {
(args.data as columnDataType)['EmployeeID'] = this.orderData['EmployeeID'];
}
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Customizing the delete confirmation dialog
By default, the Data Grid shows a confirmation dialog when attempting to delete a row. The appearance and content of this dialog can be customized to match application requirements. Customization can include changing the dialog header, icons, or button text.
To customize the delete confirmation dialog, utilize the toolbarClick event. This event is triggered when a toolbar action is performed and allows modification of dialog properties.
- Enable the confirmation dialog for deletions by setting showDeleteConfirmDialog to
trueineditSettings.- Refer to the grid Default text documentation for localization options.
The following example demonstrates how to customize the delete confirmation dialog using the toolbarClick event.
import { data } from './datasource';
import { Component, ViewChild } from '@angular/core';
import { EditService, GridComponent, GridModule, PageService, SortService, ToolbarService } from '@syncfusion/ej2-angular-grids';
import { ClickEventArgs, Item } from '@syncfusion/ej2-angular-navigations';
import { L10n } from '@syncfusion/ej2-base';
L10n.load({
'en-US': {
grid: {
'OKButton':'YES',
'CancelButton':'Discard' ,
'ConfirmDelete': 'Are you sure you want to delete the selected Record?'
}
}
});
@Component({
imports: [ GridModule],
providers: [EditService, ToolbarService, SortService, PageService],
standalone: true,
selector: 'app-root',
template: `
<ejs-grid #grid [dataSource]="data" [editSettings]="editSettings" [toolbar]="toolbar"
(toolbarClick)="toolbarClick($event)" height='250px'>
<e-columns>
<e-column field="OrderID" headerText="Order ID" isPrimaryKey="true" width="120"></e-column>
<e-column field="CustomerID" headerText="Customer ID" width="150"></e-column>
<e-column field="ShipCountry" headerText="Ship Country" width="120"></e-column>
<e-column field="ShipCity" headerText="Ship City" width="130"></e-column>
</e-columns>
</ejs-grid>
`,
})
export class AppComponent {
@ViewChild('grid')
public grid?: GridComponent;
public data?: Object[];
public editSettings?: Object;
public toolbar?: Object;
public ngOnInit(): void {
this.data = data;
this.editSettings = {
allowEditing: true,
allowAdding: true,
allowDeleting: true,
showDeleteConfirmDialog: true,
};
this.toolbar = ['Add', 'Edit', 'Delete', 'Update', 'Cancel'];
}
toolbarClick(args: ClickEventArgs): void {
if ((args.item as Item).text === 'Delete') {
const dialogObj= ((this.grid as GridComponent).editModule as any).dialogObj ;
dialogObj.header = 'Delete Confirmation Dialog';
dialogObj.showCloseIcon = true;
}
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Update boolean column value with a single click
The grid allows boolean column values to be toggled with a single click in normal editing mode. Use the column template feature to render a CheckBox for direct interaction.
The following example demonstrates how to render a CheckBox component as a template in the “Verified” column to enable single-click editing:
import { data } from './datasource';
import { Component, OnInit, ViewChild } from '@angular/core';
import { CheckBoxModule } from '@syncfusion/ej2-angular-buttons';
import { EditService, EditSettingsModel, GridComponent, GridModule, ToolbarItems, ToolbarService } from '@syncfusion/ej2-angular-grids';
@Component({
imports: [ GridModule,CheckBoxModule ],
providers: [EditService, ToolbarService ],
standalone: true,
selector: 'app-root',
template: `
<ejs-grid #grid [dataSource]="data" [editSettings]="editSettings" [toolbar]="toolbar" height="250px">
<e-columns>
<e-column field="OrderID" headerText="Order ID" isPrimaryKey="true" textAlign="Right" width="120" [validationRules]='orderIDRules'></e-column>
<e-column field="CustomerID" headerText="Customer Name" width="120" [validationRules]='customerIDRules'></e-column>
<e-column field="OrderDate" headerText="Order Date" editType="datepickeredit" format="M/d/yy" textAlign="Right" [validationRules]='dateRules' width="130" type="date"></e-column>
<e-column field="Freight" headerText="Freight" format="C2" textAlign="Right" width="90" [validationRules]='freightRules'></e-column>
<e-column field="Verified" headerText="Verified" textAlign="Right" width="90" [validationRules]='verifiedRules'>
<ng-template #template let-data>
<ejs-checkbox [(checked)]="data.Verified" (change)="onVerifiedChange(data)"></ejs-checkbox>
</ng-template>
</e-column>
</e-columns>
</ejs-grid>`
})
export class AppComponent implements OnInit {
@ViewChild('grid')
public grid: GridComponent | undefined;
public data?: object[];
public editSettings?: EditSettingsModel;
public toolbar?: ToolbarItems[];
public orderData?: object|any;
public orderIDRules?: object;
public customerIDRules?: object;
public freightRules?: object;
public dateRules?: object;
public verifiedRules?: object;
ngOnInit(): void {
this.data = data;
this.orderIDRules = { required: true };
this.customerIDRules = { required: true };
this.dateRules= { required: true };
this.verifiedRules= { required: true };
this.freightRules = { required: true, min: 1, max: 1000 };
this.editSettings = {
allowEditing: true,
allowAdding: true,
allowDeleting: true,
};
this.toolbar = ['Add', 'Edit', 'Delete', 'Update', 'Cancel'];
}
public onVerifiedChange(rowData: object | any): void {
const rowIndex = (this.grid as GridComponent).getRowIndexByPrimaryKey(
rowData.OrderID
);
(this.grid as GridComponent).updateRow(rowIndex, rowData);
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Preventing duplicate rows with custom validation
The Data Grid enables enforcement of constraints to prevent duplicate rows by customizing the validation logic within the grid setup. This ensures data integrity by restricting duplicate entries in the “Order ID” column.
To prevent adding duplicate rows in the grid, follow these steps:
-
Implement Custom Validation: Define the “orderIdCustomValidation” function to check whether the entered “Order ID” already exists in the dataSource. This allows editing an existing row without triggering a duplicate error.
-
Add Dynamic Validation Rules: Create the “orderIDRules” object to enforce unique “Order ID” values. Dynamically add this rule to the form during the
saveaction. -
Handle Validation in the actionBegin event: In the
actionBeginevent, check if therequestTypeissave. Apply the validation rule before saving and cancel the actionargs.cancel = trueif the validation fails.
For server-side validation to prevent adding duplicate rows, refer to the detailed guidance provided in the knowledge base. To display the grid’s validation tooltip instead of the alert used in the knowledge base, call the grid.editModule.formObj.validate() method in the Ajax/Fetch success function to show the grid’s tooltip validation for the server side.
import { data } from './datasource';
import { Component, OnInit, ViewChild } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { EditService, EditSettingsModel, GridComponent, GridModule, PageService, SortService, ToolbarItems, ToolbarService } from '@syncfusion/ej2-angular-grids';
@Component({
imports: [GridModule, FormsModule],
providers: [EditService, ToolbarService, SortService, PageService],
standalone: true,
selector: 'app-root',
template: `<ejs-grid #grid [dataSource]='data' [editSettings]='editSettings' [toolbar]='toolbar' height='273' (actionBegin)="actionBegin($event)">
<e-columns>
<e-column field='OrderID' headerText='Order ID' textAlign='Right' isPrimaryKey='true' width=100></e-column>
<e-column field='CustomerID' headerText='Customer ID' [validationRules]='customerIDRules' width=120></e-column>
<e-column field='Freight' headerText='Freight' textAlign= 'Right' editType= 'numericedit' width=120 format= 'C2'></e-column>
<e-column field='ShipCountry' headerText='Ship Country' editType= 'dropdownedit' width=150></e-column>
</e-columns>
</ejs-grid>`
})
export class AppComponent implements OnInit {
@ViewChild('grid') public grid?: GridComponent;
public data?: object[];
public editSettings?: EditSettingsModel;
public toolbar?: ToolbarItems[];
public orderIDRules?: object;
public customerIDRules?: object;
public orderIdCustomValidation(args: any): boolean {
return (this.grid?.dataSource as Object[]).every((data: any) => {
return data['OrderID'] + '' !== args['value'] || data['OrderID'] === (this.grid as any).editModule.editModule.args.rowData['OrderID']
});
}
public actionBegin(args: any):void {
if (args.requestType === 'save') {
(this.grid as GridComponent).editModule.formObj.addRules('OrderID', this.orderIDRules as object); // Add form validation rules dynamically.
if (!(this.grid as GridComponent).editModule.formObj.validate()) { // Check dynamically added validation rules.
args.cancel = true; // Prevent adding duplicate data action.
}
(this.grid as GridComponent).editModule.formObj.removeRules('OrderID'); // Remove form validation rules dynamically.
}
}
public ngOnInit(): void {
this.data = data;
this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Normal' };
this.toolbar = ['Add', 'Edit', 'Delete', 'Update', 'Cancel'];
this.orderIDRules = { required: true, min: [this.orderIdCustomValidation.bind(this), 'The entered value already exists in the column OrderID. Please enter a unique value.'] };
this.customerIDRules = { required: true };
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Performing CRUD actions externally
By default, the grid provides built-in editing through toolbars and inline editing. However, CRUD operations can also be triggered programmatically from external controls (custom buttons, forms, or panels outside the grid). This allows full control over when and how data operations occur.
Using a separate toolbar
To perform CRUD operations externally, use the following methods:
| Method | Purpose |
|---|---|
| addRecord | Add a new record (shows edit form if no data provided) |
| startEdit | Begin editing the selected row |
| deleteRecord | Delete the selected row |
| endEdit | Save changes when grid is in edit state |
| closeEdit | Cancel editing without saving |
The following example demonstrates external CRUD operations with a custom toolbar.
import { data } from './datasource';
import { Component, ViewChild } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { DatePickerAllModule, TimePickerModule } from '@syncfusion/ej2-angular-calendars';
import { AutoCompleteModule, DropDownListModule, MultiSelectModule } from '@syncfusion/ej2-angular-dropdowns';
import { EditService, GridComponent, GridModule, PageService, SortService, ToolbarService } from '@syncfusion/ej2-angular-grids';
import { TextBoxModule } from '@syncfusion/ej2-angular-inputs';
import { ToolbarModule } from '@syncfusion/ej2-angular-navigations';
import { ClickEventArgs } from '@syncfusion/ej2-buttons';
@Component({
imports: [
GridModule,
DatePickerAllModule,
FormsModule,
TimePickerModule,
FormsModule,
TextBoxModule,
MultiSelectModule,
AutoCompleteModule,
ToolbarModule ,
DropDownListModule
],
providers: [EditService, ToolbarService, SortService, PageService],
standalone: true,
selector: 'app-root',
template: `
<div style="display: flex">
<ejs-toolbar (clicked)="onToolbarClick($event)">
<e-items>
<e-item text="Add" id="add"></e-item>
<e-item text="Edit" id="edit"></e-item>
<e-item text="Delete" id="delete"></e-item>
<e-item text="Update" id="update"></e-item>
<e-item text="Cancel" id="cancel"></e-item>
</e-items>
</ejs-toolbar>
</div>
<div >
<ejs-grid #grid id='Batchgrid' [dataSource]='data' allowPaging='true' [pageSettings]='pageSettings'
[editSettings]='editSettings' height='220px'>
<e-columns>
<e-column field='OrderID' headerText='Order ID' width='120' textAlign='Right' isPrimaryKey='true'
[validationRules]='orderIDRules'></e-column>
<e-column field='CustomerID' headerText='Customer ID' width='120' [validationRules]='customerIDRules'
></e-column>
<e-column field='Freight' headerText='Freight' width='120' format='C2' textAlign='Right'
editType='numericedit' [validationRules]='freightRules' >
</e-column>
<e-column field='OrderDate' headerText='Order Date' width='130' format='yMd' editType='datepickeredit'
textAlign='Right' ></e-column>
<e-column field='ShipCountry' headerText='Ship Country' width='150' editType='dropdownedit'
[edit]='editparams' ></e-column>
</e-columns>
</ejs-grid>
</div>`,
})
export class AppComponent {
public data?: Object[];
@ViewChild('grid') public grid?: GridComponent;
public editSettings?: Object;
public orderIDRules?: Object;
public customerIDRules?: Object;
public freightRules?: Object;
public editparams?: Object;
public pageSettings?: Object;
public currentColumn: any;
public ngOnInit(): void {
this.data = data;
this.editSettings = {
allowEditing: true,
allowAdding: true,
allowDeleting: true,
};
this.orderIDRules = { required: true, number: true };
this.customerIDRules = { required: true };
this.freightRules = { required: true };
this.editparams = { params: { popupHeight: '300px' } };
this.pageSettings = { pageCount: 5 };
}
public onToolbarClick(args: ClickEventArgs): void {
switch ((args as any).item.id) {
case 'add':
(this.grid as GridComponent).addRecord();
break;
case 'edit':
(this.grid as GridComponent).startEdit();
break;
case 'delete':
(this.grid as GridComponent).deleteRecord();
break;
case 'update':
(this.grid as GridComponent).endEdit();
break;
case 'cancel':
(this.grid as GridComponent).closeEdit();
break;
}
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Using an external form
Instead of editing data in the grid itself, custom forms can be used to edit selected rows. When a row is selected in the grid, the corresponding data is populated in an external form. Changes made in the external form update the grid data.
The rowSelected event can be used to capture row selection and populate external form fields with the selected row’s data. The following example demonstrates editing using an external form.
import { Component, ViewChild } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
import { DropDownListModule } from '@syncfusion/ej2-angular-dropdowns';
import { EditService, GridComponent, GridModule, PageService, RowSelectEventArgs, SortService, ToolbarService } from '@syncfusion/ej2-angular-grids';
import { NumericTextBoxAllModule, TextBoxModule } from '@syncfusion/ej2-angular-inputs';
import{ data } from "./datasource"
@Component({
imports: [ GridModule, FormsModule, TextBoxModule, ButtonModule, NumericTextBoxAllModule,DropDownListModule],
providers: [EditService, ToolbarService, SortService, PageService],
standalone: true,
selector: 'app-root',
template: `
<div class="row" >
<div class="col-xs-6 col-md-3">
<div>
<div class="form-row">
<div class="form-group col-md-12">
<label for="orderedit">OrderID</label>
<input class="form-control" [(ngModel)]="selectedProduct.OrderID" type="number" disabled />
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12">
<label for="customeredit">CustomerID</label>
<ejs-textbox [(value)]="selectedProduct.CustomerID"></ejs-textbox>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12">
<label for="freightedit">Frieght</label>
<ejs-numerictextbox [(value)]="selectedProduct.Freight"></ejs-numerictextbox>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12">
<label for="countryedit">ShipCountry</label>
<ejs-dropdownlist [(value)]="selectedProduct.ShipCountry" [dataSource]="dropdown" [fields]="dropdownFields">
</ejs-dropdownlist>
</div>
</div>
</div>
<button ejs-button id="btn" (click)="save()">Save</button>
</div>
<div class="col-xs-6 col-md-9">
<ejs-grid #grid [dataSource]="orders" height="315" width="500px" (rowSelected)="rowSelectHandler($event)" [editSettings]="editSettings">
<e-columns>
<e-column field="OrderID" headerText="OrderID" isPrimaryKey="true" textAlign="Right" width="120"></e-column>
<e-column field="CustomerID" headerText="CustomerID" textAlign="Right" width="120"></e-column>
<e-column field="Freight" headerText="Freight" textAlign="Right" format="C2" width="120"></e-column>
<e-column field="ShipCountry" headerText="ShipCountry" textAlign="Right" width="120"></e-column>
</e-columns>
</ejs-grid>
</div>
</div>
`,
})
export class AppComponent {
public orders:Object[] = data;
@ViewChild('grid') public grid?:GridComponent;
public dropdown: Object[] = [
{ shipCountry: 'Germany' },
{ shipCountry: 'Brazil' },
{ shipCountry: 'France' },
{ shipCountry: 'Belgium' },
{ shipCountry: 'Switzerland' },
{ shipCountry: 'Venezuela' },
{ shipCountry: 'USA' },
{ shipCountry: 'Mexico' },
{ shipCountry: 'Italy' },
{ shipCountry: 'Sweden' },
{ shipCountry: 'Finland' },
{ shipCountry: 'Spain' },
{ shipCountry: 'Canada' },
{ shipCountry: 'Portugal' },
{ shipCountry: 'Denmark' },
{ shipCountry: 'Austria' },
{ shipCountry: 'UK' },
{ shipCountry: 'Ireland' },
{ shipCountry: 'Norway' },
{ shipCountry: 'Argentina' },
];
public selectedProduct: Order = new Order();
public dropdownFields: Object = { text: 'shipCountry', value: 'shipCountry' };
public editSettings: Object = { allowEditing: true };
save(): void {
const index = (this.grid as GridComponent).getSelectedRowIndexes()[0];
(this.grid as GridComponent).updateRow(index, this.selectedProduct);
}
rowSelectHandler(args: RowSelectEventArgs ): void {
(this as any).selectedProduct = { ...args.data };
}
}
export class Order {
OrderID?: number;
CustomerID?: string;
Freight?: number;
ShipCountry?: string;
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Make a grid column always editable
To keep a column editable at all times, use a column template and handle input through the created event and updateRow method.
Example: Editable “Freight” column textbox template.
import { data } from './datasource';
import { Component, OnInit, ViewChild } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { DatePickerAllModule, TimePickerModule } from '@syncfusion/ej2-angular-calendars';
import { AutoCompleteModule, MultiSelectModule } from '@syncfusion/ej2-angular-dropdowns';
import { EditService, GridComponent, GridModule, PageService, parentsUntil, SortService, ToolbarService } from '@syncfusion/ej2-angular-grids';
import { TextBoxModule } from '@syncfusion/ej2-angular-inputs';
@Component({
imports: [
GridModule,
DatePickerAllModule,
FormsModule,
TimePickerModule,
FormsModule,
TextBoxModule,
MultiSelectModule,
AutoCompleteModule
],
providers: [EditService, ToolbarService, SortService, PageService],
standalone: true,
selector: 'app-root',
template: `<ejs-grid #grid [dataSource]='data' [editSettings]='editSettings' height='315px' (created)="created()">
<e-columns>
<e-column field='OrderID' headerText='Order ID' textAlign='Right' isPrimaryKey='true' width=120></e-column>
<e-column field='OrderDate' headerText='Order Date' width=130 textAlign='Right' format='yMd'></e-column>
<e-column field='ShipCountry' headerText='Ship Country' width=140></e-column>
<e-column field='Freight' headerText='Receipt Amount' textAlign= 'Right' width=150>
<ng-template #template let-data>
<input id='' value='' class='custemp' type='text' style='width: 100%'>
</ng-template>
</e-column>
</e-columns>
</ejs-grid>`
})
export class AppComponent implements OnInit {
public data?: object[];
@ViewChild('grid') public grid?: GridComponent;
public editSettings?: Object;
ngOnInit(): void {
this.data = data;
}
created() {
(this.grid as GridComponent).element.addEventListener('keyup', function (e) { // Bind the keyup event for the grid.
if ((e.target as HTMLElement).classList.contains('custemp')) { // Based on this condition, you can find whether the target is an input element or not.
var row = parentsUntil(e.target as HTMLElement, 'e-row');
var rowIndex = (row as HTMLFormElement)['rowIndex']; // Get the row index.
var uid = row.getAttribute('data-uid');
var grid = (document.getElementsByClassName('e-grid')[0] as HTMLFormElement)['ej2_instances'][0];
var rowData = grid.getRowObjectFromUID(uid).data; // Get the row data.
rowData.Freight = ((e.target as HTMLFormElement)['value']); // Update the new value for the corresponding column.
grid.updateRow(rowIndex, rowData); // Update the modified value in the row data.
}
});
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));If a template column has an associated
fieldproperty, values from the input will be stored in that field in the data object.
Troubleshooting: Editing works only for the first row
If editing or deleting only works for the first row in the grid, the isPrimaryKey property is likely not configured. The primary key is essential for identifying which row to edit or delete. Without it, the grid cannot distinguish between rows.
Solution: Set isPrimaryKey to true on the column that contains unique identifiers:
<e-column field='OrderID' headerText='Order ID' width='100' isPrimaryKey='true'></e-column>See also
- Cascading DropDownList with Data Grid editing
- Render Tab inside the dialog editing
- Apply animation for grid edit dialog in Data Grid
- CRUD operations using ASP.NET core web api methods in Data Grid
- How to restrict ArrowUp increase and ArrowDown decrease value in grid numeric cell in Data Grid
- How to use DropDownList and Combo-Box in Batch-edit mode of Data Grid
- How to use CellEditArgs event in Data Grid
- How to render grid with add form always in Data Grid
- How to show the numeric key pad in mobile device when edit the number column in Data Grid
- How to enable inline editing in Angular 4 Data Grid/Table