How can I help you?
Inline Editing in Angular Grid Component
19 Mar 202624 minutes to read
The Angular Grid component provides an efficient inline editing feature, enabling direct modification of row or cell values within the grid. Inline editing is ideal for streamlining data entry and updates without invoking a separate form. In normal edit mode, the selected record enters an editable state, allowing updates to cell values which are then saved back to the data source.
To enable in-line editing in the grid component, set the editSettings.mode property to Normal. This property determines the editing mode of 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' 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' headerText='Freight' textAlign= 'Right' editType= 'numericedit' [validationRules]='freightIDRules' 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 freightIDRules?: 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: 5 };
this.freightIDRules={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));
Normaledit mode is default mode of editing.- When enabling editing, it is necessary to set the isPrimaryKey property value to
truefor the unique column.- For basic editing setup and configuration, refer to the Edit Feature Setup.
Automatically update a specific column based on changes in another column
The Cell Edit Template feature enables automatic updating of a column’s value whenever a value in another column is edited. This powerful feature enables dynamic calculations and real-time updates to column values based on changes in related columns, streamlining data entry workflows.
To enable this functionality:
- Define the editType property to specify the editor type for editing.
- Provide an object for the edit property to customize editing behavior.
In the following example, the “Total Cost” column value is updated based on changes to the “Unit Price” and “Unit In Stock” columns during editing.
import { productData } 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, EditSettingsModel, GridComponent, GridModule, PageService, SortService, ToolbarItems, ToolbarService } from '@syncfusion/ej2-angular-grids';
import { TextBoxModule } from '@syncfusion/ej2-angular-inputs';
import { ChangeEventArgs } from '@syncfusion/ej2-buttons';
@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"
[toolbar]="toolbar" height="273px">
<e-columns>
<e-column field="ProductID" headerText="Product ID" textAlign="Right" isPrimaryKey="true" [validationRules]='orderIDRules' width="100"></e-column>
<e-column field="ProductName" headerText="Product Name" width="120" [validationRules]=' productNameRules'></e-column>
<e-column field="UnitPrice" headerText="Unit Price" editType="numericedit" [edit]="priceParams" width="150" [validationRules]='unitIDRules' format="C2" textAlign="Right"></e-column>
<e-column field="UnitsInStock" headerText="Units In Stock" editType="numericedit" [edit]="stockParams" [validationRules]='stockIDRules' width="150" textAlign="Right"></e-column>
<e-column field="TotalCost" headerText="Total Cost" width="150" [allowEditing]='false' format="C2" textAlign="Right"></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 priceParams?: Object;
public stockParams?: Object;
public orderIDRules?: object;
public unitIDRules?: object;
public stockIDRules?: object;
public productNameRules?: object;
ngOnInit(): void {
this.data = productData;
this.editSettings = {
allowEditing: true,
allowAdding: true,
allowDeleting: true
};
this.orderIDRules = { required: true };
this. productNameRules = { required: true };
this.unitIDRules={ required: true, min: 1 }
this.unitIDRules={ required: true, min: 1 }
this.toolbar = ['Add', 'Edit', 'Delete', 'Update', 'Cancel'];
this.priceParams = { params: { change: this.calculateTotalCost.bind(this) } };
this.stockParams = { params: { change: this.calculateTotalCost.bind(this) } };
}
calculateTotalCost(args:ChangeEventArgs): void {
const formEle = ((this.grid as GridComponent).element.querySelector('form') as HTMLFormElement)['ej2_instances'][0];
formEle.getInputElement('TotalCost').value = formEle.getInputElement('UnitPrice').value * formEle.getInputElement('UnitsInStock').value;
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Cancel edit based on condition
The Grid provides the ability to cancel the edit operations for particular row or cell based on specific conditions. This feature allows controlling whether editing should be allowed or prevented for certain rows or cells in the grid. This functionality is achieved by leveraging the actionBegin event of the Grid component. This event is triggered when a CRUD (Create, Read, Update, Delete) operation is initiated in the grid.
This customization is useful when restricting editing for certain rows, such as read-only data, calculated values, or protected information. It helps maintain data integrity and ensures that only authorized changes can be made in the grid.
To cancel the edit operation based on a specific condition, handle the actionBegin event of the Grid component and check the requestType parameter. This parameter indicates the type of action being performed:
| Request Type | Description |
|---|---|
beginEdit |
Editing an existing record |
add |
Creating a new record |
save |
Updating a new or existing record |
delete |
Deleting an existing record |
Apply the desired condition and cancel the operation by setting the args.cancel property to true.
Example: Prevent CRUD actions for rows where the “Role” column equals “Admin”.
import { data } from './datasource';
import { Component, OnInit } from '@angular/core';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
import { EditEventArgs, EditService, EditSettingsModel, GridModule, ToolbarItems, ToolbarService } from '@syncfusion/ej2-angular-grids';
@Component({
imports: [ GridModule,ButtonModule],
providers: [EditService, ToolbarService],
standalone: true,
selector: 'app-root',
template: `<button ejs-button id="small" (click)="btnClick($event)">Grid is Addable
</button>
<div class="control-section" style="padding-top:20px">
<ejs-grid [dataSource]='data' [editSettings]='editSettings'
[toolbar]='toolbar' (actionBegin)="actionBegin($event)" height='240px'>
<e-columns>
<e-column field='EmployeeID' headerText='Employee ID' textAlign= 'Right' isPrimaryKey='true' [validationRules]='orderIDRules' width=100></e-column>
<e-column field='EmployeeName' headerText='Employee Name' [validationRules]='customerNameRules' width=120 format= 'C2'></e-column>
<e-column field='Role' headerText='Role' [validationRules]='roleIDRules' width=120></e-column>
<e-column field='EmployeeCountry' headerText='Employee Country' editType= 'dropdownedit' width=150></e-column>
</e-columns>
</ejs-grid>
</div>`
})
export class AppComponent implements OnInit {
public data?: object[];
public editSettings?: EditSettingsModel;
public toolbar?: ToolbarItems[];
public isAddable: boolean = true;
public orderIDRules?: object;
public roleIDRules?: object;
public customerNameRules?: 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.roleIDRules = { required: true, minLength: 5 };
this.customerNameRules = { required: true }
}
actionBegin(args: EditEventArgs) {
if (args.requestType == 'beginEdit' && args.rowData as { Role?: string }['Role'] == 'Admin') {
args.cancel = true;
}
else if (args.requestType == 'delete' && (args as any).data[0].Role == 'Admin') {
args.cancel = true;
}
else if (args.requestType == 'add') {
if (!this.isAddable) {
args.cancel = true;
}
}
}
btnClick(args: MouseEvent) {
(args.target as HTMLElement).innerText == 'GRID IS ADDABLE' ? ((args.target as HTMLElement).innerText = 'Grid is Not Addable') : ((args.target as HTMLElement).innerText = 'Grid is Addable');
this.isAddable = !this.isAddable;
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Perform CRUD actions programmatically
Programmatic CRUD operations enable creating, reading, updating, and deleting data through code rather than manual user interaction. This approach provides flexibility for advanced data manipulation workflows. The following table outlines key methods for programmatic CRUD operations:
| Method | Description | Usage |
|---|---|---|
| addRecord | Add a new record to the grid | Pass the data parameter to add a record. Use the index parameter for a specific position. Without parameters, creates an empty row at index zero. |
| startEdit | Change the selected row to edit state | First select the row, then invoke this method. The selected row enters edit mode immediately. Without row selection along with default showConfirmDialog enabled state, “No records selected for edit operation” dialog appears. |
| updateRow | Update row data in the data source | Provide the row index and the updated data as parameters. The data source updates accordingly. |
| setCellValue | Update a particular cell in a row | Provide the primary key value, field name, and new value. Changes appear visually in the UI only (not persisted). Useful for unbound columns, auto-calculated columns, and formula columns. |
| deleteRecord | Remove a selected row from the grid | First select the row, then invoke this method. The selected row is immediately removed. Without row selection along with default showConfirmDialog enabled state, “No records selected for delete operation” dialog appears. |
In both
NormalandDialogediting modes, these methods can be used.
import { columnDataType, data } from './datasource';
import { Component, OnInit, ViewChild } from '@angular/core';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
import { EditService, EditSettingsModel, GridComponent, GridModule, ToolbarService } from '@syncfusion/ej2-angular-grids';
@Component({
imports: [ GridModule, ButtonModule],
providers: [EditService, ToolbarService],
standalone: true,
selector: 'app-root',
template: `
<button ejs-button id='edit' (click)='clickEvents($event)'>Edit</button>
<button ejs-button id='add' (click)='clickEvents($event)'>Add</button>
<button ejs-button id='delete' (click)='clickEvents($event)'>Delete</button>
<button ejs-button id='updaterow' (click)='clickEvents($event)'>Update Row</button>
<button ejs-button id='updatecell' (click)='clickEvents($event)'>Update cell</button>
<div class="control-section" style="padding-top:20px">
<ejs-grid #grid id="Grid" [dataSource]='data' [editSettings]='editSettings' height='273'>
<e-columns>
<e-column field='OrderID' headerText='Order ID' textAlign='Right' width=120 [validationRules]='orderIDRules' isPrimaryKey='true'></e-column>
<e-column field='CustomerID' [validationRules]='customerIDRules' headerText='Customer ID' width=150></e-column>
<e-column field='ShipCity' headerText='Ship City' [validationRules]='cityIDRules' width=150></e-column>
<e-column field='ShipName' headerText='Ship Name' [validationRules]='shipIDRules' width=150></e-column>
</e-columns>
</ejs-grid>
</div> `
})
export class AppComponent implements OnInit {
public editSettings?: EditSettingsModel;
public data?: object[];
@ViewChild('grid')
public grid?: GridComponent;
public orderIDRules?: object;
public customerIDRules?: object;
public freightIDRules?: object;
public cityIDRules?:object;
public shipIDRules?:object;
ngOnInit(): void {
this.data = data;
this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true ,};
this.orderIDRules = { required: true };
this.cityIDRules = { required: true };
this. shipIDRules = { required: true };
this.customerIDRules = { required: true, minLength: 5 };
this.freightIDRules={required: true, min: 1, max:1000 }
}
clickEvents(args:MouseEvent){
if((args.target as HTMLElement).id==='edit')
{
(this.grid as GridComponent).startEdit();
}
else if((args.target as HTMLElement).id==='add')
{
(this.grid as GridComponent).addRecord({ "OrderID": Math.floor(Math.random() * 100000), "CustomerID": this.generateCustomerId(),
"ShipCity": this.generateShipCity(), "ShipName": this.generateShipName() });
}
else if((args.target as HTMLElement).id==='delete'){
(this.grid as GridComponent).deleteRecord();
}
else if((args.target as HTMLElement).id==='updaterow')
{
(this.grid as GridComponent).updateRow(0, {OrderID:10248,CustomerID: 'RTER', ShipCity: 'America', ShipName: 'Hanari'});
}
else
{
(this.grid as GridComponent).setCellValue(((this.grid as GridComponent).currentViewData[0] as columnDataType).OrderID,'CustomerID','Value Changed');
}
}
generateCustomerId(): string {
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
let result = '';
for (let i = 0; i < 5; i++) {
result += characters.charAt(Math.floor(Math.random() * characters.length));
}
return result;
}
// Generate a random ShipCity
generateShipCity(): string {
const cities = ['London', 'Paris', 'New York', 'Tokyo', 'Berlin'];
return cities[Math.floor(Math.random() * cities.length)];
}
// Generate a random Freight value
generateFreight(): number {
return Math.random() * 100;
}
// Generate a random ShipName
generateShipName(): string {
const names = ['Que Delícia', 'Bueno Foods', 'Island Trading', 'Laughing Bacchus Winecellars'];
return names[Math.floor(Math.random() * names.length)];
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Show confirmation dialog for deletion
The built-in confirmation dialog enhances data safety by requesting user confirmation before deleting records. Enable this dialog by setting showDeleteConfirmDialog in editSettings to true (default is false).
import { data } from './datasource';
import { Component, OnInit, ViewChild } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { SwitchModule } from '@syncfusion/ej2-angular-buttons';
import { DatePickerAllModule, TimePickerModule } from '@syncfusion/ej2-angular-calendars';
import { AutoCompleteModule, MultiSelectModule } from '@syncfusion/ej2-angular-dropdowns';
import { EditService, EditSettingsModel, GridComponent, 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,
SwitchModule
],
providers: [EditService, ToolbarService, SortService, PageService],
standalone: true,
selector: 'app-root',
template: `
<div>
<label>Enable/Disable show delete confirmation dialog</label>
<ejs-switch id="switch1" [(checked)]="enableShowDeleteConfirmDialog"
(change)="toggleShowDeleteConfirmDialog()"></ejs-switch>
</div>
<ejs-grid #grid [dataSource]="data" [editSettings]="editSettings" [toolbar]="toolbar" height="270px">
<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" format="C2"
[validationRules]="freightRules"></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[] = ['Add', 'Delete', 'Update', 'Cancel'];
public orderIDRules: Object = {};
public customerIDRules: Object = {};
public freightRules: Object = {};
public enableShowConfirmDialog: boolean = true;
public enableShowDeleteConfirmDialog: boolean = false;
ngOnInit(): void {
this.data = data;
this.editSettings = {
allowEditing: true,
allowAdding: true,
allowDeleting: true,
mode: 'Normal'
};
this.orderIDRules = { required: true, number: true };
this.customerIDRules = { required: true };
this.freightRules = { min: 1, max: 1000 };
}
toggleShowDeleteConfirmDialog(): void {
(this.grid as GridComponent).editSettings.showDeleteConfirmDialog = this.enableShowDeleteConfirmDialog;
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));The showDeleteConfirmDialog property supports all editing modes.
Display default values for columns when adding records
Preset column values streamline data entry for new records. Set defaultValue for columns in the grid configuration to ensure these fields are pre-filled in new rows.
Example using default column 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, 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='273px'>
<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'
defaultValue= 'HANAR' [validationRules]='customerIDRules' width=120>
</e-column>
<e-column field='Freight' headerText='Freight' textAlign= 'Right'
editType= 'numericedit' [validationRules]='freightIDRules'
width=120 defaultValue= '1' format= 'C2'></e-column>
<e-column field='ShipCountry' headerText='Ship Country'
editType='dropdownedit' defaultValue= 'France' 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 freightIDRules?: 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.freightIDRules={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));Delete multiple rows
Multiple row deletion is supported via the in-built toolbar or through methods.
Using the toolbar: Set the toolbar and selectionSettings.type to Multiple. Select rows and use the toolbar delete icon to remove them.
import { data } from './datasource';
import { Component, OnInit } from '@angular/core';
import { EditService, EditSettingsModel, GridModule, ToolbarItems, ToolbarService } from '@syncfusion/ej2-angular-grids';
@Component({
imports: [ GridModule ],
providers: [EditService, ToolbarService],
standalone: true,
selector: 'app-root',
template: `
<ejs-grid [dataSource]='data' [toolbar]='toolbar' [editSettings]='editSettings'
[selectionSettings]="selectOptions" height='273px'>
<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' headerText='Freight' textAlign= 'Right'
editType= 'numericedit' width=120 format= 'C2'
[validationRules]='freightIDRules'></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 selectOptions?: Object;
public orderIDRules?: object;
public customerIDRules?: object;
public freightIDRules?: object;
ngOnInit(): void {
this.data = data;
this.editSettings = {
allowEditing: true,
allowAdding: true,
allowDeleting: true,
mode: 'Normal',
};
this.orderIDRules = { required: true };
this.customerIDRules = { required: true, minLength: 5 };
this.freightIDRules={required: true, min: 1, max:1000 }
this.toolbar = ['Delete'];
this.selectOptions = { type: 'Multiple' };
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Selected records can also be deleted using the
Deletekey.
Using methods:
Multiple rows can be deleted programmatically using the following methods.
-
deleteRecord - This method deletes a record with the given options. If the
fieldname(primary key field) anddataparameters are not provided, the grid deletes the selected records.this.grid.deleteRecord(); -
deleteRow - This method deletes a visible row by providing the corresponding
<tr>element. UsegetSelectedRowsto retrieve the selected rows and iterate over them. For each row, pass the<tr>element todeleteRowto initiate deletion. This approach enables selective deletion based on the<tr>elements obtained fromgetSelectedRows.const selectedRows: any[] = this.grid.getSelectedRows(); selectedRows.forEach((row: HTMLTableRowElement) => { this.grid.deleteRow(row); });
Use
selectionSettings.type=Multipleand consider enablingshowDeleteConfirmDialogproperty of theeditSettingsto prevent accidental deletions.
import { data } from './datasource';
import { Component, OnInit, ViewChild } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
import { DatePickerAllModule, TimePickerModule } from '@syncfusion/ej2-angular-calendars';
import { AutoCompleteModule, MultiSelectModule } from '@syncfusion/ej2-angular-dropdowns';
import { EditService, EditSettingsModel, GridComponent, GridModule, PageService, SortService, ToolbarService } from '@syncfusion/ej2-angular-grids';
import { TextBoxModule } from '@syncfusion/ej2-angular-inputs';
@Component({
imports: [
GridModule,
DatePickerAllModule,
FormsModule,
TimePickerModule,
FormsModule,
TextBoxModule,
MultiSelectModule,
AutoCompleteModule,
ButtonModule
],
providers: [EditService, ToolbarService, SortService, PageService],
standalone: true,
selector: 'app-root',
template: `
<button ejs-button id='delete' (click)='clickDelete($event)'>Delete Multiple
</button>
<div class="control-section" style="padding-top:20px">
<ejs-grid #grid [dataSource]='data' [editSettings]='editSettings'
[selectionSettings]="selectOptions" height='273px'>
<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' headerText='Freight'
textAlign= 'Right' editType= 'numericedit' width=120
format= 'C2' [validationRules]='freightIDRules'></e-column>
<e-column field='ShipCountry' headerText='Ship Country'
editType= 'dropdownedit' width=150></e-column>
</e-columns>
</ejs-grid>
</div>`
})
export class AppComponent implements OnInit {
public data?: object[];
public editSettings?: EditSettingsModel;
public selectOptions?: Object;
@ViewChild('grid')
public grid?: GridComponent;
public orderIDRules?: object;
public customerIDRules?: object;
public freightIDRules?: object;
ngOnInit(): void {
this.data = data;
this.editSettings = {
allowEditing: true,
allowAdding: true,
allowDeleting: true,
};
this.selectOptions = { type: 'Multiple' };
this.orderIDRules = { required: true };
this.customerIDRules = { required: true, minLength: 5 };
this.freightIDRules={required: true, min: 1, max:1000 }
}
clickDelete(args:MouseEvent) {
const selectedRows: Element[] = (this.grid as GridComponent).getSelectedRows();
selectedRows.forEach((row:Element) => {
(this.grid as GridComponent).deleteRow(row as HTMLTableRowElement);
});
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Add new rows at the bottom of the grid
The Grid component enables seamless addition of new rows at the bottom of the grid, inserting records at the end of the existing data set. This convenient feature proves particularly useful for intuitive record addition without requiring scroll repositioning, improving workflow efficiency.
By default, new row’s form is inserted at the top of the grid for data entry. To change this behavior, set the newRowPosition property in the editSettings configuration to Bottom. This property controls the position where the new row form is inserted.
Example using newRowPosition:
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, NewRowPosition, 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',
template: `
<div style="display: flex">
<label style="padding: 30px 17px 0 0;"> Select new row position:</label>
<ejs-dropdownlist style="padding: 26px 0 0 0" index="0" width="100"
[dataSource]="positionData" (change)="changePosition($event)">
</ejs-dropdownlist>
</div>
<div>
<ejs-grid #batchgrid id='Batchgrid' [dataSource]='data' allowPaging='true' [editSettings]="editSettings" [pageSettings]='pageSettings' [toolbar]='toolbar' height='185'>
<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('batchgrid')
public grid?: GridComponent;
public editSettings?: Object;
public toolbar?: string[];
public orderIDRules?: Object;
public customerIDRules?: Object;
public freightRules?: Object;
public editparams?: Object;
public pageSettings?: Object;
public positionData: { text: string; value: string }[] = [
{ text: 'Top', value: 'Top' },
{ text: 'Bottom', value: 'Bottom' },
];
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 changePosition(args: ChangeEventArgs): void {
(this.grid as GridComponent).editSettings.newRowPosition= (args.value as NewRowPosition);
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
- The newRowPosition property is supported for
NormalandBatchediting modes.- When newRowPosition is set to
Bottom, the grid displays a blank row form at the bottom by default for data entry. However, when the data is saved or updated, it is inserted at the top of the grid.
Show add new row always in grid
The Syncfusion® Angular Grid simplifies record addition by consistently presenting a blank “add new row” form within the grid. To enable this feature, set the showAddNewRow property within the editSettings configuration to true. This enables continuous record addition. The add new row displays at either the top or bottom of the grid content, depending on the newRowPosition property of editSettings. By default, the add new row displays at the top of the grid content.
The following sample demonstrates to add a new record continuously using showAddNewRow property.
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, 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],
standalone: true,
selector: 'app-root',
template: `<ejs-grid [dataSource]='data' [editSettings]='editSettings'
[toolbar]='toolbar' height='250px'>
<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' headerText='Freight' textAlign= 'Right'
editType= 'numericedit' [validationRules]='freightIDRules'
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 freightIDRules?: object;
ngOnInit(): void {
this.data = data;
this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, newRowPosition: 'Top', showAddNewRow: true };
this.toolbar = ['Add', 'Edit', 'Delete', 'Update', 'Cancel'];
this.orderIDRules = { required: true };
this.customerIDRules = { required: true, minLength: 5 };
this.freightIDRules={required: true, min: 1 }
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));To save newly added records, press the Enter key or click the Update button on the toolbar after filling the add form.
Limitations
- This feature is supported only for
Inline/Normalediting mode and is not compatible with other edit modes. - The new blank add row form will always be displayed at the top, even when the new row position is set to the bottom for virtual scrolling and infinite scrolling enabled grids.
- This feature is not compatible with the column virtualization feature.
Move focus to a particular cell when editing a row
The Grid component enables moving focus to a specific cell when editing a row, rather than the default behavior of focusing on the first cell. This feature improves the editing experience by automatically focusing on the cell requiring immediate attention.
To achieve this functionality, leverage the recordDoubleClick event of the Grid component. The recordDoubleClick event is triggered when a row is double-clicked, indicating intent to edit. Handle this event and programmatically move focus to the desired cell within the row.
Example moving focus to a specific cell:
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 { EditEventArgs, EditService, EditSettingsModel, GridComponent, GridModule, IEditCell, PageService, RecordDoubleClickEventArgs, 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='220'
allowPaging='true' (actionComplete)='actionComplete($event)'
(recordDoubleClick)='recordDoubleClick($event)'>
<e-columns>
<e-column field='OrderID' headerText='Order ID' textAlign='Right' isPrimaryKey='true' width=120 type='number' [validationRules]='orderIDRules'></e-column>
<e-column field='CustomerID' headerText='Customer ID' [validationRules]='customerIDRules' width=140 type='string'></e-column>
<e-column field='Freight' headerText='Freight' editType='numericedit' textAlign='Right' width=120 format='c2' [validationRules]='freightIDRules'></e-column>
<e-column field='OrderDate' headerText='Order Date' textAlign= 'Right' width=140 editType='datetimepickeredit' [format]='formatOptions' ></e-column>
<e-column field='ShipCountry' headerText='Ship Country' editType='dropdownedit' width=150 [edit]='params'></e-column>
</e-columns>
</ejs-grid>`
})
export class AppComponent implements OnInit {
public data?: object[];
public editSettings?: EditSettingsModel;
public formatOptions?: object;
public params?: IEditCell;
public fieldName: string|any = ''; // Explicitly declare the type
@ViewChild('grid')
public grid?: GridComponent;
public orderIDRules?: object;
public customerIDRules?: object;
public freightIDRules?: object;
ngOnInit(): void {
this.data = data;
this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, mode: "Normal" };
this.formatOptions = { type: 'dateTime', format: 'M/d/y hh:mm a' };
this.orderIDRules = { required: true };
this.customerIDRules = { required: true, minLength: 5 };
this.freightIDRules={required: true, min: 1, max:1000 }
this.params = {
params: {
popupHeight: "300px"
}
};
}
actionComplete(args:EditEventArgs) {
if (args.requestType === "beginEdit") {
// focus the column
((args.form as HTMLFormElement).elements[(this.grid as GridComponent).element.getAttribute("id") + this.fieldName] as HTMLInputElement).focus();
}
}
recordDoubleClick(args:RecordDoubleClickEventArgs) {
this.fieldName = (this.grid as GridComponent).getColumnByIndex((args.cellIndex as number)).field;
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Enable single-click editing
Enabling single-click editing in the Syncfusion® Angular Grid’s Normal editing mode is a valuable and intuitive feature that makes a row editable with just one click. This seamless experience is achieved by using the startEdit and endEdit methods for rapid, efficient data modification.
To implement this feature, bind the mouseup event for the Grid and, within the event handler, call the startEdit and endEdit methods based on the clicked target element. This ensures editing mode is triggered when clicking on a specific element within the Grid.
The following sample demonstrates to enable editing in a single click using the mouseup event along with the load event:
import { data } from './datasource';
import { Component, OnInit, ViewChild } from '@angular/core';
import { EditService, EditSettingsModel, GridComponent, GridModule, PageService, ToolbarItems, ToolbarService } from '@syncfusion/ej2-angular-grids';
@Component({
imports: [ GridModule],
providers: [EditService, PageService, ToolbarService],
standalone: true,
selector: 'app-root',
template: `
<ejs-grid #grid [dataSource]='data' height='220px' [editSettings]='editSettings' [toolbar]='toolbar' allowPaging='true' (load)='load()'>
<e-columns>
<e-column field='OrderID' headerText='Order ID' textAlign='Right' width=100 isPrimaryKey='true'></e-column>
<e-column field='CustomerID' headerText='Customer ID' width=120></e-column>
<e-column field='Freight' headerText='Freight' textAlign= 'Right' width=120 format= 'C2'></e-column>
<e-column field='ShipCountry' headerText='Ship Country' width=150></e-column>
</e-columns>
</ejs-grid>`
})
export class AppComponent implements OnInit {
public data?: object[];
public toolbar?: ToolbarItems[];
@ViewChild('grid')
public grid?: GridComponent;
public editSettings?: EditSettingsModel;
ngOnInit(): void {
this.data = data;
this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Normal' };
this.toolbar = ['Add', 'Edit', 'Delete', 'Update', 'Cancel'];
}
load(){
(this.grid as GridComponent).element.addEventListener('mouseup', (e) => {
if ((e.target as HTMLElement).classList.contains("e-rowcell")) {
if ((this.grid as GridComponent).isEdit){
(this.grid as GridComponent).endEdit();
}
let index: number = parseInt(((e.target as HTMLElement).getAttribute("Index") as string));
(this.grid as GridComponent).selectRow(index);
(this.grid as GridComponent).startEdit();
}
});
}
}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 rows
Editing can be restricted for designated rows using the actionBegin event. Set args.cancel = true based on custom condition checks in the event handler.
In the below demo, the rows which are having the value for “Ship Country” column as “France” is prevented from editing.
import { columnDataType, 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 { EditEventArgs, 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'
(actionBegin)="actionBegin($event)" 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' 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.editSettings = { allowEditing: true, mode: 'Normal' };
this.toolbar = ['Edit', 'Update', 'Cancel'];
this.orderIDRules = { required: true };
this.customerIDRules = { required: true };
this.freightRules = { min:1,max:1000 };
}
actionBegin(args: EditEventArgs) {
if (args.requestType === 'beginEdit' && (args.rowData as columnDataType).ShipCountry === 'France') {
args.cancel = true;
}
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));