In Batch edit mode, when you double-click on the 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
]../api/grid/edit/#batchsave) method.
To enable Batch edit, set the editSettings.mode
as Batch
.
ej.grids.Grid.Inject(ej.grids.Edit, ej.grids.Toolbar);
var grid = new ej.grids.Grid({
dataSource: data,
toolbar: ['Add', 'Delete', 'Update', 'Cancel'],
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Batch' },
columns: [
{ field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 100, isPrimaryKey: true },
{ field: 'CustomerID', headerText: 'Customer ID', width: 120, },
{ field: 'Freight', headerText: 'Freight', textAlign: 'Right', editType: 'numericedit', width: 120, format: 'C2' },
{ field: 'ShipCountry', headerText: 'Ship Country', editType: 'dropdownedit', width: 150 }
],
height: 273
});
grid.appendTo('#Grid');
<!DOCTYPE html><html lang="en"><head>
<title>EJ2 Grid</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Typescript Grid Control">
<meta name="author" content="Syncfusion">
<link href="index.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-base/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-grids/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-buttons/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-popups/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-richtexteditor/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-navigations/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-dropdowns/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-lists/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-inputs/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-calendars/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-notifications/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-splitbuttons/styles/material.css" rel="stylesheet">
<style>
.e-row[aria-selected="true"] .e-customizedExpandcell {
background-color: #e0e0e0;
}
.e-grid.e-gridhover tr[role='row']:hover {
background-color: #eee;
}
.e-expand::before {
content: '\e5b8';
}
.empImage {
margin: 6px 16px;
float: left;
width: 50px;
height: 50px;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/21.2.3/dist/ej2.min.js" type="text/javascript"></script>
<script src="es5-datasource.js" type="text/javascript"></script>
</head>
<body>
<div id="container">
<div id="Grid"></div>
</div>
<script>
var ele = document.getElementById('container');
if(ele) {
ele.style.visibility = "visible";
}
</script>
<script src="index.js" type="text/javascript"></script>
</body></html>
If a column’s allowEditing property is set to false, then the focus can be skipped in that non-editable column by clicking the tab or shift-tab key while in batch edit mode.
You can update the column value based on another column edited value in Batch mode by using the Cell Edit Template feature.
In the below demo, we have update the TotalCost
column value based on the UnitPrice
and UnitInStock
column value while editing.
var priceElem;
var priceObj;
var stockElem;
var stockObj;
ej.grids.Grid.Inject(ej.grids.Edit, ej.grids.Toolbar);
var grid = new ej.grids.Grid({
dataSource: productData,
editSettings: {
allowEditing: true,
allowAdding: true,
allowDeleting: true,
mode: 'Batch',
newRowPosition: 'Top'
},
allowPaging: true,
pageSettings: { pageCount: 5 },
toolbar: ['Add', 'Delete', 'Update', 'Cancel'],
columns: [
{
field: 'ProductID',
isPrimaryKey: true,
headerText: 'Product ID',
textAlign: 'Right',
validationRules: { required: true, number: true },
width: 140
},
{
field: 'ProductName',
headerText: 'Product Name',
validationRules: { required: true },
width: 140
},
{
field: 'UnitPrice',
headerText: 'UnitPrice',
textAlign: 'Right',
edit: {
create: function() {
priceElem = document.createElement('input');
return priceElem;
},
read: function() {
return priceObj.value;
},
destroy: function() {
priceObj.destroy();
},
write: function(args) {
var rowData = args.rowData;
var rowIndex = grid.getRowInfo(args.row).rowIndex;
priceObj = new ej.inputs.NumericTextBox({
value: args.rowData[args.column.field],
change: function(args) {
var totalCostValue = args.value * rowData['UnitsInStock'];
grid.updateCell(rowIndex, 'TotalCost', totalCostValue);
}
});
priceObj.appendTo(priceElem);
}
},
width: 140,
format: 'C2',
validationRules: { required: true }
},
{
field: 'UnitsInStock',
headerText: 'Units In Stock',
textAlign: 'Right',
edit: {
create: function() {
stockElem = document.createElement('input');
return stockElem;
},
read: function() {
return stockObj.value;
},
destroy: function() {
stockObj.destroy();
},
write: function(args) {
var rowData = args.rowData;
var rowIndex = grid.getRowInfo(args.row).rowIndex;
stockObj = new ej.inputs.NumericTextBox({
value: args.rowData[args.column.field],
change: function(args) {
var totalCostValue = args.value * rowData['UnitPrice'];
grid.updateCell(rowIndex, 'TotalCost', totalCostValue);
}
});
stockObj.appendTo(stockElem);
}
},
width: 140,
validationRules: { required: true }
},
{
field: 'TotalCost',
headerText: 'Total Unit Cost',
textAlign: 'Right',
width: 140,
format: 'C2',
}
]
});
grid.appendTo('#Grid');
grid.cellEdit= function(args){
if(args.columnName == "TotalCost"){
args.cancel= true;
}
}
<!DOCTYPE html><html lang="en"><head>
<title>EJ2 Grid</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Typescript Grid Control">
<meta name="author" content="Syncfusion">
<link href="index.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-base/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-grids/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-buttons/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-popups/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-richtexteditor/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-navigations/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-dropdowns/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-lists/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-inputs/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-calendars/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-notifications/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-splitbuttons/styles/material.css" rel="stylesheet">
<style>
.e-row[aria-selected="true"] .e-customizedExpandcell {
background-color: #e0e0e0;
}
.e-grid.e-gridhover tr[role='row']:hover {
background-color: #eee;
}
.e-expand::before {
content: '\e5b8';
}
.empImage {
margin: 6px 16px;
float: left;
width: 50px;
height: 50px;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/21.2.3/dist/ej2.min.js" type="text/javascript"></script>
<script src="es5-datasource.js" type="text/javascript"></script>
</head>
<body>
<div id="container">
<div id="Grid"></div>
</div>
<script>
var ele = document.getElementById('container');
if(ele) {
ele.style.visibility = "visible";
}
</script>
<script src="index.js" type="text/javascript"></script>
</body></html>
You can prevent the CRUD operations of the Batch edit Grid by using condition in the cellEdit
, beforeBatchAdd
and beforeBatchDelete
events for Edit, Add and Delete actions respectively.
In the below demo, we prevent the CRUD operation based on the Role
column value. If the Role Column is Employee
, we are unable to edit/delete that row.
ej.grids.Grid.Inject(ej.grids.Edit, ej.grids.Toolbar);
var isAddable = true;
var grid = new ej.grids.Grid({
dataSource: data,
toolbar: ['Add', 'Delete', 'Update', 'Cancel'],
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Batch' },
columns: [
{ field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 100, isPrimaryKey: true },
{ field: 'Role', headerText: 'Role', width: 120, },
{ field: 'Freight', headerText: 'Freight', textAlign: 'Right', editType: 'numericedit', width: 120, format: 'C2' },
{ field: 'ShipCountry', headerText: 'Ship Country', editType: 'dropdownedit', width: 150 }
],
cellEdit: cellEdit,
beforeBatchAdd: beforeBatchAdd,
beforeBatchDelete: beforeBatchDelete,
height: 240
});
grid.appendTo('#Grid');
function cellEdit(args) {
if (args.rowData['Role'] == 'Employee') {
args.cancel = true;
}
}
function beforeBatchAdd(args) {
if (!isAddable) {
args.cancel = true;
}
}
function beforeBatchDelete(args) {
if (args.rowData['Role'] == 'Employee') {
args.cancel = true;
}
}
var button = document.createElement('button');
button.innerText = 'Grid is Addable';
document.body.insertBefore(button, document.body.children[0]);
button.addEventListener('click', btnClick.bind(this));
function btnClick(args) {
args.target.innerText == 'Grid is Addable' ? (args.target.innerText = 'Grid is Not Addable') : (args.target.innerText = 'Grid is Addable');
isAddable = !isAddable;
}
<!DOCTYPE html><html lang="en"><head>
<title>EJ2 Grid</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Typescript Grid Control">
<meta name="author" content="Syncfusion">
<link href="index.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-base/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-grids/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-buttons/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-popups/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-richtexteditor/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-navigations/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-dropdowns/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-lists/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-inputs/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-calendars/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-notifications/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-splitbuttons/styles/material.css" rel="stylesheet">
<style>
.e-row[aria-selected="true"] .e-customizedExpandcell {
background-color: #e0e0e0;
}
.e-grid.e-gridhover tr[role='row']:hover {
background-color: #eee;
}
.e-expand::before {
content: '\e5b8';
}
.empImage {
margin: 6px 16px;
float: left;
width: 50px;
height: 50px;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/21.2.3/dist/ej2.min.js" type="text/javascript"></script>
<script src="es5-datasource.js" type="text/javascript"></script>
</head>
<body>
<div id="container">
<div id="Grid"></div>
</div>
<script>
var ele = document.getElementById('container');
if(ele) {
ele.style.visibility = "visible";
}
</script>
<script src="index.js" type="text/javascript"></script>
</body></html>
By default, grid will show the confirm dialog when saving or canceling or performing any actions like filtering, sorting, etc.
ej.grids.Grid.Inject(ej.grids.Edit, ej.grids.Toolbar);
var grid = new ej.grids.Grid({
dataSource: data,
toolbar: ['Add', 'Edit', 'Delete', 'Update', 'Cancel'],
editSettings: { showConfirmDialog: true, showDeleteConfirmDialog: true, allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Batch' },
columns: [
{ field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 100, isPrimaryKey: true },
{ field: 'CustomerID', headerText: 'Customer ID', width: 120, },
{ field: 'Freight', headerText: 'Freight', textAlign: 'Right', editType: 'numericedit', width: 120, format: 'C2' },
{ field: 'ShipCountry', headerText: 'Ship Country', editType: 'dropdownedit', width: 150 }
],
height: 273
});
grid.appendTo('#Grid');
<!DOCTYPE html><html lang="en"><head>
<title>EJ2 Grid</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Typescript Grid Control">
<meta name="author" content="Syncfusion">
<link href="index.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-base/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-grids/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-buttons/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-popups/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-richtexteditor/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-navigations/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-dropdowns/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-lists/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-inputs/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-calendars/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-notifications/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-splitbuttons/styles/material.css" rel="stylesheet">
<style>
.e-row[aria-selected="true"] .e-customizedExpandcell {
background-color: #e0e0e0;
}
.e-grid.e-gridhover tr[role='row']:hover {
background-color: #eee;
}
.e-expand::before {
content: '\e5b8';
}
.empImage {
margin: 6px 16px;
float: left;
width: 50px;
height: 50px;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/21.2.3/dist/ej2.min.js" type="text/javascript"></script>
<script src="es5-datasource.js" type="text/javascript"></script>
</head>
<body>
<div id="container">
<div id="Grid"></div>
</div>
<script>
var ele = document.getElementById('container');
if(ele) {
ele.style.visibility = "visible";
}
</script>
<script src="index.js" type="text/javascript"></script>
</body></html>
editSettings.showConfirmDialog
requires theeditSettings.mode
to beBatch
- If
editSettings.showConfirmDialog
set tofalse
, then confirmation dialog does not display in batch editing.
When using batch mode, the TAB key allows you to edit or move to the next cell or row from the current record by default. Using the grid’s load event, the same functionality can also be achieved by pressing the arrow keys. Additionally, the editCell
method of the grid allows for cells to be made editable with a single click.
In the following sample, the load event of the Grid will be used to bind the keydown event handler. When any arrow key is pressed, the editCell
method of the Grid will be used to identify the next or previous cell (td) and set it to be editable. Additionally, it is possible to enable editing of a cell with a single click by utilizing the editCell
method within the created event of the Grid.
var grid = new ej.grids.Grid({
dataSource: data,
allowPaging: true,
enableHover: false,
created: created,
load: load,
editSettings: {
allowEditing: true,
allowAdding: true,
allowDeleting: true,
mode: 'Batch',
},
toolbar: ['Add', 'Edit', 'Delete', 'Update', 'Cancel'],
columns: [
{ field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 100, isPrimaryKey: true,
visible: false, validationRules: { required: true, number: true } },
{ field: 'CustomerID', headerText: 'Customer ID', width: 120, validationRules: { required: true }
},
{ field: 'Freight', headerText: 'Freight', format: 'C2', width: 100, textAlign: 'Right' },
{ field: 'OrderDate', headerText: 'Order Date', editType: 'datepickeredit', format: 'yMd', width: 100},
{ field: 'ShipCountry', headerText: 'Ship Country', width: 100 },
],
});
grid.appendTo('#Grid');
function created(args) {
grid.getContentTable().addEventListener('click', function (args) {
if (args.target.classList.contains('e-rowcell')) {
grid.editModule.editCell(parseInt(args.target.getAttribute('index')),
grid.getColumnByIndex(parseInt(args.target.getAttribute('data-colindex'))).field);
}
});
}
function load() {
grid.element.addEventListener('keydown', function (e) {
var closesttd = e.target.closest('td');
if (e.keyCode === 39 && !isNullOrUndefined(closesttd.nextSibling)) {
editACell(closesttd.nextSibling);
}
if (e.keyCode === 37 && !isNullOrUndefined(closesttd.previousSibling) &&
!grid.getColumnByIndex(
parseInt(closesttd.previousSibling.getAttribute('data-colindex'))).isPrimaryKey)
{
editACell(closesttd.previousSibling);
}
if (e.keyCode === 40 && !isNullOrUndefined(closesttd.closest('tr').nextSibling)) {
editACell(
closesttd.closest('tr').nextSibling.querySelectorAll('td')[
parseInt(closesttd.getAttribute('data-colindex'))]);
}
if ( e.keyCode === 38 && !isNullOrUndefined(closesttd.closest('tr').previousSibling)) {
editACell(
closesttd.closest('tr').previousSibling.querySelectorAll('td')[
parseInt(closesttd.getAttribute('data-colindex'))]);
}
});
}
function editACell(args) {
grid.editModule.editCell(
parseInt(args.getAttribute('index')),
grid.getColumnByIndex(parseInt(args.getAttribute('data-colindex'))).field);
}
<!DOCTYPE html><html lang="en"><head>
<title>EJ2 Grid</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Typescript Grid Control">
<meta name="author" content="Syncfusion">
<link href="index.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-base/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-grids/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-buttons/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-popups/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-richtexteditor/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-navigations/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-dropdowns/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-lists/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-inputs/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-calendars/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-notifications/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-splitbuttons/styles/material.css" rel="stylesheet">
<style>
.e-row[aria-selected="true"] .e-customizedExpandcell {
background-color: #e0e0e0;
}
.e-grid.e-gridhover tr[role='row']:hover {
background-color: #eee;
}
.e-expand::before {
content: '\e5b8';
}
.empImage {
margin: 6px 16px;
float: left;
width: 50px;
height: 50px;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/21.2.3/dist/ej2.min.js" type="text/javascript"></script>
<script src="es5-datasource.js" type="text/javascript"></script>
</head>
<body>
<div id="container">
<div id="Grid"></div>
</div>
<script>
var ele = document.getElementById('container');
if(ele) {
ele.style.visibility = "visible";
}
</script>
<script src="index.js" type="text/javascript"></script>
</body></html>