Batch editing in Angular Treegrid component
9 Jan 202324 minutes to read
In Batch edit mode, when you double-click on the tree grid cell, then the target cell changed to edit state. You can bulk save (added, changed and deleted data in the single request) to data source by click on the toolbar’s Update
button or by externally invoking the batchSave
method. To enable Batch edit, set the editSettings.mode
as Batch
.
import { Component, OnInit } from '@angular/core';
import { projectData } from './datasource';
import { EditSettingsModel, ToolbarItems } from '@syncfusion/ej2-angular-treegrid';
@Component({
selector: 'app-container',
template: `<ejs-treegrid [dataSource]='data' parentIdMapping='parentID' idMapping='TaskID' [toolbar]='toolbar' [treeColumnIndex]='1' height='270' [editSettings]='editSettings' >
<e-columns>
<e-column field='TaskID' headerText='Task ID' [isPrimaryKey]='true' textAlign='Right' width=90></e-column>
<e-column field='TaskName' headerText='Task Name' textAlign='Left' width=180></e-column>
<e-column field='Priority' headerText='Priority' textAlign='Right' width=90></e-column>
<e-column field='StartDate' headerText='Start Date' textAlign='Right' format='yMd' type='date' editType='datepickeredit' width=90></e-column>
<e-column field='Duration' headerText='Duration' textAlign='Right' width=80></e-column>
</e-columns>
</ejs-treegrid>`
})
export class AppComponent implements OnInit {
public data: Object[];
public editSettings: EditSettingsModel;
public toolbar: ToolbarItems[];
ngOnInit(): void {
this.data = projectData;
this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Batch' };
this.toolbar = ['Add', 'Edit', 'Delete', 'Update', 'Cancel'];
}
}
import { NgModule,ViewChild } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { TreeGridModule } from '@syncfusion/ej2-angular-treegrid';
import { PageService, SortService, FilterService,EditService,ToolbarService } from '@syncfusion/ej2-angular-treegrid';
import { AppComponent } from './app.component';
import {ButtonModule} from '@syncfusion/ej2-angular-buttons';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';
/**
* Module
*/
@NgModule({
imports: [
BrowserModule,
TreeGridModule,
ButtonModule,
DropDownListAllModule,
],
declarations: [AppComponent],
bootstrap: [AppComponent],
providers: [PageService,
SortService,
FilterService,
EditService,
ToolbarService]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);
- You can get the details of added records, changed records and deleted records by the
getBatchChanges
method in tree grid.- To update a particular cell in the row, use the
updateCell
method. In this method, pass the row index of the data source, field name, and new value for a particular cell. This can be done only in the batch editing mode of the tree grid.
Automatically update the column based on another column edited value in batch mode
Update the column value based on another column edited value in the Batch mode by using the Cell Edit Template feature.
You can get the row detail by passing the target element as argument to getRowInfo
method in the tree grid.
In the following demo, we have update the price column value based on the units and unitPrice column value while batch editing:
import { Component, OnInit, ViewChild } from '@angular/core';
import { summaryData } from './datasource';
import { EditSettingsModel, ToolbarItems, TreeGridComponent, IEditCell } from '@syncfusion/ej2-angular-treegrid';
import { NumericTextBox } from '@syncfusion/ej2-inputs';
@Component({
selector: 'app-container',
template: `<ejs-treegrid #treegrid id="treegrid" [dataSource]='data' [toolbar]='toolbarOptions' [treeColumnIndex]='1' height='270' [editSettings]='editSettings' childMapping='subtasks' (cellEdit)="cellEdit($event)">
<e-columns>
<e-column field='ID' headerText='ID' [isPrimaryKey]='true' textAlign='Right' width=90></e-column>
<e-column field='Name' headerText='Name' textAlign='Left' width=180></e-column>
<e-column field='units' headerText='Units' textAlign='Right' editType="numericedit" [edit]="unitsParams" format="C2" width=120></e-column>
<e-column field='unitPrice' headerText='Unit Price' textAlign='Right' editType="numericedit" [edit]="unitPriceParams" width=120></e-column>
<e-column field='price' headerText='Total Price' textAlign='Right' format="C2" width=110></e-column>
</e-columns>
</ejs-treegrid>`
})
export class AppComponent implements OnInit {
@ViewChild('treegrid')
public treegrid: TreeGridComponent;
public data: Object[];
public editSettings: EditSettingsModel;
public toolbarOptions: ToolbarItems[];
public unitsParams: IEditCell;
public unitPriceParams: IEditCell;
public unitsElem: HTMLElement;
public unitsObj: NumericTextBox;
public unitPriceElem: HTMLElement;
public unitPriceObj: NumericTextBox;
ngOnInit(): void {
this.data = summaryData;
this.editSettings = {
allowEditing: true,
allowAdding: true,
allowDeleting: true,
mode: 'Batch'
};
this.toolbarOptions = ['Add', 'Delete', 'Update', 'Cancel'];
this.unitsParams = {
create: () => {
this.unitsElem = document.createElement('input');
return this.unitsElem;
},
read: () => {
return this.unitsObj.value;
},
destroy: () => {
this.unitsObj.destroy();
},
write: args => {
var rowData = args.rowData;
var rowIndex = this.treegrid.getRowInfo(args.row).rowIndex;
this.unitsObj = new NumericTextBox({
value: args.rowData[args.column.field],
change: function(args) {
var totalCostValue = args.value * rowData['unitPrice'];
this.treegrid.updateCell(rowIndex, 'price', totalCostValue);
}.bind(this)
});
this.unitsObj.appendTo(this.unitsElem);
}
};
this.unitPriceParams = {
create: () => {
this.unitPriceElem = document.createElement('input');
return this.unitPriceElem;
},
read: () => {
return this.unitPriceObj.value;
},
destroy: () => {
this.unitPriceObj.destroy();
},
write: args => {
var rowData = args.rowData;
var rowIndex = this.treegrid.getRowInfo(args.row).rowIndex;
this.unitPriceObj = new NumericTextBox({
value: args.rowData[args.column.field],
change: function(args) {
var totalCostValue = args.value * rowData['unitPrice'];
this.treegrid.updateCell(rowIndex, 'price', totalCostValue);
}.bind(this)
});
this.unitPriceObj.appendTo(this.unitPriceElem);
}
};
}
cellEdit(args) {
if (args.columnName == 'price') {
args.cancel = true;
}
}
}
import { NgModule,ViewChild } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { TreeGridModule } from '@syncfusion/ej2-angular-treegrid';
import { PageService, SortService, FilterService,EditService,ToolbarService } from '@syncfusion/ej2-angular-treegrid';
import { AppComponent } from './app.component';
import {ButtonModule} from '@syncfusion/ej2-angular-buttons';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';
/**
* Module
*/
@NgModule({
imports: [
BrowserModule,
TreeGridModule,
ButtonModule,
DropDownListAllModule,
],
declarations: [AppComponent],
bootstrap: [AppComponent],
providers: [PageService,
SortService,
FilterService,
EditService,
ToolbarService]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);
Cancel edit based on condition in batch mode
Prevent the CRUD operations of the Batch edit tree grid by using condition in the cellEdit, beforeBatchAdd and beforeBatchDelete events for Edit, Add, and Delete actions respectively.
In the following demo, the CRUD operation have been prevented based on the Priority column value. If the Priority Column is Normal, that row cannot be edited or deleted.
import { Component, OnInit } from '@angular/core';
import { projectData } from './datasource';
import { EditSettingsModel, ToolbarItems } from '@syncfusion/ej2-angular-treegrid';
@Component({
selector: 'app-container',
template: `<button (click)="btnClick($event)">TreeGrid is Addable</button>
<ejs-treegrid [dataSource]='data' parentIdMapping='parentID' idMapping='TaskID' [toolbar]='toolbar' [treeColumnIndex]='1' height='270' [editSettings]='editSettings' (cellEdit)="cellEdit($event)" (beforeBatchAdd)="beforeBatchAdd($event)" (beforeBatchDelete)="beforeBatchDelete($event)" >
<e-columns>
<e-column field='TaskID' headerText='Task ID' [isPrimaryKey]='true' textAlign='Right' width=90></e-column>
<e-column field='TaskName' headerText='Task Name' textAlign='Left' width=180></e-column>
<e-column field='Priority' headerText='Priority' textAlign='Right' width=120></e-column>
<e-column field='Duration' headerText='Duration' textAlign='Right' width=110></e-column>
</e-columns>
</ejs-treegrid>`
})
export class AppComponent implements OnInit {
public data: object[];
public editSettings: EditSettingsModel;
public toolbar: ToolbarItems[];
public isAddable: boolean = true;
ngOnInit(): void {
this.data = projectData;
this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Batch' };
this.toolbar = ['Add', 'Edit', 'Delete', 'Update', 'Cancel'];
}
cellEdit(args) {
if (args.rowData['Priority'] == 'Normal') {
args.cancel = true;
}
}
beforeBatchAdd(args) {
if (!this.isAddable) {
args.cancel = true;
}
}
beforeBatchDelete(args) {
if (args.rowData['Priority'] == 'Normal') {
args.cancel = true;
}
}
btnClick(args) {
args.target.innerText == 'TreeGrid is Addable' ? (args.target.innerText = 'TreeGrid is Not Addable') : (args.target.innerText = 'TreeGrid is Addable');
this.isAddable = !this.isAddable;
}
}
import { NgModule,ViewChild } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { TreeGridModule } from '@syncfusion/ej2-angular-treegrid';
import { PageService, SortService, FilterService,EditService,ToolbarService } from '@syncfusion/ej2-angular-treegrid';
import { AppComponent } from './app.component';
import {ButtonModule} from '@syncfusion/ej2-angular-buttons';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';
/**
* Module
*/
@NgModule({
imports: [
BrowserModule,
TreeGridModule,
ButtonModule,
DropDownListAllModule,
],
declarations: [AppComponent],
bootstrap: [AppComponent],
providers: [PageService,
SortService,
FilterService,
EditService,
ToolbarService]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);
Confirmation dialog
By default, the tree grid will show the confirm dialog when saving, cancelling, or performing any actions like filtering, sorting, and more.
import { Component, OnInit } from '@angular/core';
import { projectData } from './datasource';
import { EditSettingsModel, ToolbarItems } from '@syncfusion/ej2-angular-treegrid';
@Component({
selector: 'app-container',
template: `<ejs-treegrid [dataSource]='data' parentIdMapping='parentID' idMapping='TaskID' [toolbar]='toolbar' [treeColumnIndex]='1' height='270' [editSettings]='editSettings' >
<e-columns>
<e-column field='TaskID' headerText='Task ID' [isPrimaryKey]='true' textAlign='Right' width=90></e-column>
<e-column field='TaskName' headerText='Task Name' textAlign='Left' width=180></e-column>
<e-column field='Priority' headerText='Priority' textAlign='Right' width=90></e-column>
<e-column field='StartDate' headerText='Start Date' textAlign='Right' format='yMd' type='date' editType='datepickeredit' width=90></e-column>
<e-column field='Duration' headerText='Duration' textAlign='Right' width=80></e-column>
</e-columns>
</ejs-treegrid>`
})
export class AppComponent implements OnInit {
public data: object[];
public editSettings: EditSettingsModel;
public toolbar: ToolbarItems[];
ngOnInit(): void {
this.data = projectData;
this.editSettings = {
showConfirmDialog: true, showDeleteConfirmDialog: true,
allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Batch'
};
this.toolbar = ['Add', 'Edit', 'Delete', 'Update', 'Cancel'];
}
}
import { NgModule,ViewChild } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { TreeGridModule } from '@syncfusion/ej2-angular-treegrid';
import { PageService, SortService, FilterService,EditService,ToolbarService } from '@syncfusion/ej2-angular-treegrid';
import { AppComponent } from './app.component';
import {ButtonModule} from '@syncfusion/ej2-angular-buttons';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';
/**
* Module
*/
@NgModule({
imports: [
BrowserModule,
TreeGridModule,
ButtonModule,
DropDownListAllModule,
],
declarations: [AppComponent],
bootstrap: [AppComponent],
providers: [PageService,
SortService,
FilterService,
EditService,
ToolbarService]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);
- The editSettings.showConfirmDialog requires the editSettings.mode to be Batch
- If the
editSettings.showConfirmDialog
set to false, then the confirmation dialog does not display in the batch editing.
How to save cell programmatically
To save a cell in tree grid, use the saveCell
method in batch edit mode as in the following sample.
import { Component, OnInit } from '@angular/core';
import { projectData } from './datasource';
import { EditSettingsModel, ToolbarItems } from '@syncfusion/ej2-angular-treegrid';
@Component({
selector: 'app-container',
template: `<ejs-treegrid [dataSource]='data' parentIdMapping='parentID' idMapping='TaskID' [toolbar]='toolbar' [treeColumnIndex]='1' height='270' [editSettings]='editSettings' >
<e-columns>
<e-column field='TaskID' headerText='Task ID' [isPrimaryKey]='true' textAlign='Right' width=90></e-column>
<e-column field='TaskName' headerText='Task Name' textAlign='Left' width=180></e-column>
<e-column field='Priority' headerText='Priority' textAlign='Right' width=90></e-column>
<e-column field='StartDate' headerText='Start Date' textAlign='Right' format='yMd' type='date' editType='datepickeredit' width=90></e-column>
<e-column field='Duration' headerText='Duration' textAlign='Right' width=80></e-column>
</e-columns>
</ejs-treegrid>`
})
export class AppComponent implements OnInit {
public data: object[];
public editSettings: EditSettingsModel;
public toolbar: ToolbarItems[];
ngOnInit(): void {
this.data = projectData;
this.editSettings = {
showConfirmDialog: true, showDeleteConfirmDialog: true,
allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Batch'
};
this.toolbar = ['Add', 'Edit', 'Delete', 'Update', 'Cancel'];
}
}
import { NgModule,ViewChild } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { TreeGridModule } from '@syncfusion/ej2-angular-treegrid';
import { PageService, SortService, FilterService,EditService,ToolbarService } from '@syncfusion/ej2-angular-treegrid';
import { AppComponent } from './app.component';
import {ButtonModule} from '@syncfusion/ej2-angular-buttons';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';
/**
* Module
*/
@NgModule({
imports: [
BrowserModule,
TreeGridModule,
ButtonModule,
DropDownListAllModule,
],
declarations: [AppComponent],
bootstrap: [AppComponent],
providers: [PageService,
SortService,
FilterService,
EditService,
ToolbarService]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);
To edit a cell in the tree grid, use the
editCell
method. In this method, you need to pass the row index and field name to locate the cell which needs to be edited.