The Syncfusion JavaSript DataGrid control is a high-performance grid component that helps display and manipulate large amounts of data in a tabular format. Its feature set includes rich functionalities: data binding, sorting, grouping, editing, filtering, swiping, dragging, resizing, loading more items, pull-to-refresh, and exporting to Excel and PDF file formats. In this blog, we are going to walk you through the procedure to implement column bulk-edit support for the JavaScript DataGrid (ES5 platform) through the context menu event, also known as a right-click event.
Column bulk editing is a feature that helps us easily edit multiple cells in a column at once in JavaScript DataGrid. It saves a lot of time and reduces the workload. We’ll start this blog by creating a sample of a simple JavaScript DataGrid project with remote data binding. Then, I’ll show you the edit dialog with the desired column type when right-clicking on a grid column.
Let’s see about them along with code examples!
Please follow these steps to render the DataGrid in the JavaScript platform (ES5).
Step 1: First, let’s create the index.html file with a JS CDN (content delivery network) script reference like in the following code.
<html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0" charset="utf-8" /> <script src="https://cdn.syncfusion.com/ej2/dist/ej2.min.js" type="text/javascript"></script> <link href="https://cdn.syncfusion.com/ej2/material.css" rel="stylesheet"> <style> body { touch-action: none; } .e-grid { margin: 30px; } .title { text-align: center; } </style> </head> <body> <div class="stackblitz-container material"> <div class="control-section"> <div class="content-wrapper"> <h4 class="title">Multi Column Update</h4> <div id="sample"></div> </div> </div> </div> </body> </html>
Step 2: Here, we will use the DataGrid to display employees’ details. So, let’s create the employee.js file and add the following basic grid rendering codes to it.
function renderGrid() { gridInstance = new ej.grids.Grid({ columns: [ { field: "EmpID", isPrimaryKey: true, allowEditing: false }, { field: "Name", headerText: "Employee Name", validationRules: { required: true } }, ], dataSource: [], height: "auto", allowPaging: true, pageSettings: { pageSize: 15 }, selectionSettings: { type: "Multiple", persistSelection: true } }); document.body.appendChild(ej.base.createElement("div", { id: "sample" })); gridInstance.appendTo("#sample"); } // event triggered when DOM load complete. document.addEventListener('DOMContentLoaded', (event) => { //Render grid renderGrid(); });
Step 3: Then, add this Employee.js file as the source in the index.html.
Step 4: Now, open the index.html file. It will display the created grid sample with two columns, Id and Employee Name, like in the following screenshot.
Note: Please refer to the Getting Started documentation to render the DataGrid in the JavaScript platform (ES5).
Here, I have created an ASP.NET Core application for the API implementation.
Step 1: Right-click on the project and choose the Manage NuGet Packages option like in the following screenshot.
Step 2: Now, switch to the Browse tab and search for the Syncfusion.EJ2.AspNet.Core NuGet package. Then, install it in your application.
In the ASP.NET Core application sample, no database connection is used. Employee records are stored in the static property and returned as an API response.
Refer to the following code.
public static List<EmployeeDetails> GetAllRecords() { List<EmployeeDetails> empList = new List<EmployeeDetails>(); empList.Add(new EmployeeDetails() { EmpID = 1, PhoneNumber = 412134, Name = "Raja", Designation = "Software Engineer", Reporter = "Selva", BranchLocation = "Eymard", TeamName = "Consulting", DateOfJoin = new DateTime(2018, 06, 01), EmpStatus = "Confirmed" }); empList.Add(new EmployeeDetails() { EmpID = 2, PhoneNumber = 333111, Name = "Suresh", Designation = "Software Engineer", Reporter = "Selva", BranchLocation = "Eymard", TeamName = "Consulting", DateOfJoin = new DateTime(2020, 02, 01), EmpStatus = "Probation" }); empList.Add(new EmployeeDetails() { EmpID = 3, PhoneNumber = 431891, Name = "Selva", Designation = "Team Lead", Reporter = "Karthik", BranchLocation = "Eymard", TeamName = "Consulting", DateOfJoin = new DateTime(2013, 02, 01), EmpStatus = "Confirmed" }); empList.Add(new EmployeeDetails() { EmpID = 4, PhoneNumber = 312211, Name = "Guna", Designation = "Software Engineer", Reporter = "Selva", BranchLocation = "Eymard", TeamName = "Consulting", DateOfJoin = new DateTime(2015, 01, 01), EmpStatus = "Confirmed" }); empList.Add(new EmployeeDetails() { EmpID = 5, PhoneNumber = 412134, Name = "Ravi", Designation = "Software Engineer", Reporter = "Selva", BranchLocation = "Eymard", TeamName = "Consulting", DateOfJoin = new DateTime(2019, 03, 01), EmpStatus = "Confirmed" }); empList.Add(new EmployeeDetails() { EmpID = 6, PhoneNumber = 412135, Name = "Priya", Designation = "Software Engineer", Reporter = "Selva", BranchLocation = "Eymard", TeamName = "Consulting", DateOfJoin = new DateTime(2015, 07, 01), EmpStatus = "Confirmed" }); empList.Add(new EmployeeDetails() { EmpID = 7, PhoneNumber = 412136, Name = "Dhana", Designation = "Software Engineer", Reporter = "Vino", BranchLocation = "Mathura", TeamName = "Consulting", DateOfJoin = new DateTime(2015, 09, 01), EmpStatus = "Confirmed" }); empList.Add(new EmployeeDetails() { EmpID = 8, PhoneNumber = 412137, Name = "Karthik", Designation = "Manager", Reporter = "", BranchLocation = "Mathura", TeamName = "Consulting", DateOfJoin = new DateTime(2010, 02, 01), EmpStatus = "Confirmed" }); empList.Add(new EmployeeDetails() { EmpID = 9, PhoneNumber = 411138, Name = "Vino", Designation = "Team Lead", Reporter = "Raj", BranchLocation = "Mathura", TeamName = "Consulting", DateOfJoin = new DateTime(2014, 02, 01), EmpStatus = "Confirmed" }); empList.Add(new EmployeeDetails() { EmpID = 10,PhoneNumber = 412139, Name = "Raji", Designation = "Software Engineer", Reporter = "Vino", BranchLocation = "Mathura", TeamName = "Consulting", DateOfJoin = new DateTime(2015, 05, 01), EmpStatus = "Probation" }); empList.Add(new EmployeeDetails() { EmpID = 11,PhoneNumber = 412140, Name = "Vijay", Designation = "Software Engineer", Reporter = "Vino", BranchLocation = "Mathura", TeamName = "Consulting", DateOfJoin = new DateTime(2020, 02, 01), EmpStatus = "Confirmed" }); empList.Add(new EmployeeDetails() { EmpID = 12,PhoneNumber = 412141, Name = "Raj", Designation = "Manager", Reporter = "", BranchLocation = "Mathura", TeamName = "Consulting", DateOfJoin = new DateTime(2010, 02, 01), EmpStatus = "Confirmed" }); return empList; }
Implement the Get API to return all the employee records.
public IActionResult GetEmployees([FromBody]DataManagerRequest dm) { IEnumerable DataSource = Employees; DataOperations operation = new DataOperations(); int count = DataSource.Cast<EmployeeDetails>().Count(); if (dm.Skip != 0) { DataSource = operation.PerformSkip(DataSource, dm.Skip); //Paging } if (dm.Take != 0) { DataSource = operation.PerformTake(DataSource, dm.Take); } return dm.RequiresCounts ? Json(new { result = DataSource, count = count }) : Json(DataSource); }
Note:
The modal object class DataManagerRequest is referenced from the library using Syncfusion.EJ2.Base.
Implement the bulk-record update logic like in the following code example.
public IActionResult UpdateEmployeeDetails([FromBody]CRUDModel<EmployeeDetails> batchmodel) { if (batchmodel != null && batchmodel.Changed != null) { for (var i = 0; i < batchmodel.Changed.Count(); i++) { var ord = batchmodel.Changed[i]; EmployeeDetails val = Employees.Where(or => or.EmpID == ord.EmpID).FirstOrDefault(); val.EmpID = ord.EmpID; val.Name = ord.Name; val.Designation = ord.Designation; val.BranchLocation = ord.BranchLocation; val.Reporter = ord.Reporter; val.EmpStatus = ord.EmpStatus; val.DateOfJoin = ord.DateOfJoin; val.TeamName = ord.TeamName; val.PhoneNumber = ord.PhoneNumber; } } var data = Employees.ToList(); return Json(data); }
Note:
The modal object class CRUDModal is referenced from the library using Syncfusion.EJ2.Base.
Now, follow these steps to bind the Get and Update APIs to the grid.
Step 1: Switch to the Employee.js file and create an instance of DataManager with both the Get (url) and Update (crudUrl) URLs.
var hostUrl = "http://localhost:64515/"; var gridDataSource = new ej.data.DataManager({ url: hostUrl + "Employee/GetEmployees", crudUrl: hostUrl + "Employee/UpdateEmployeeDetails", adaptor: new ej.data.UrlAdaptor() });
Note: We should provide the server API running the URL as the hostUrl in the js file.
Step 2: Then, assign the DataManager instance to the grid’s dataSource property.
Sample code
function renderGrid() { gridInstance = new ej.grids.Grid({ columns: [ { field: "EmpID", isPrimaryKey: true, allowEditing: false }, { field: "Name", headerText: "Employee Name", validationRules: { required: true } }, ], dataSource: gridDataSource, height: "auto", allowPaging: true, pageSettings: { pageSize: 15 }, selectionSettings: { type: "Multiple", persistSelection: true } }); document.body.appendChild(ej.base.createElement("div", { id: "sample" })); gridInstance.appendTo("#sample"); }
Step 3: Now, configure the grid column settings to display the employee details in the grid.
function renderGrid() { gridInstance = new ej.grids.Grid({ columns: [ { field: "EmpID", isPrimaryKey: true, allowEditing: false }, { field: "Name", headerText: "Employee Name", validationRules: { required: true } }, { field: "Designation", headerText: "Designation" }, { field: "TeamName", headerText: "Team" }, { field: "PhoneNumber", headerText: "Phone", type: "number" }, { field: "Reporter", headerText: "Reporter", editType: "dropdownedit", foreignKeyField: "ReporterId", foreignKeyValue: "Reporter", dataSource: Reporters }, { field: "BranchLocation", headerText: "Branch" }, { field: "DateOfJoin", headerText: "Date Of Joined", type: "date", format: { type: "date", format: "MMM dd yyyy" }, editType: "datepickeredit", edit: { params: { format: "MMM dd yyyy" } } }, { field: "EmpStatus", headerText: "Status", editType: "dropdownedit", foreignKeyField: "EmpStatusId", foreignKeyValue: "EmpStatus", dataSource: StatusList } ], dataSource: gridDataSource, height: "auto", allowPaging: true, pageSettings: { pageSize: 15 }, selectionSettings: { type: "Multiple", persistSelection: true } }); document.body.appendChild(ej.base.createElement("div", { id: "sample" })); gridInstance.appendTo("#sample"); }
Step 4: Then, save all the files and run the server API.
Now, we have finished the API implementation and bound the remote data to the DataGrid.
Now, add a reference to Ej2GridExtendedFeature.js in the grid page (Index.html) like in the following screenshot.
Note: You can download the script file.
Now, we are going to invoke the enableBulkColumnEdit() method from the created event of the JavaScript DataGrid to enable the column bulk-edit feature.
Refer to the following screenshot.
Sample code
function renderGrid() { gridInstance = new ej.grids.Grid({ columns: [ { field: "EmpID", isPrimaryKey: true, allowEditing: false }, { field: "Name", headerText: "Employee Name", validationRules: { required: true } }, { field: "Designation", headerText: "Designation" }, { field: "TeamName", headerText: "Team" }, { field: "PhoneNumber", headerText: "Phone", type: "number" }, { field: "Reporter", headerText: "Reporter", editType: "dropdownedit", foreignKeyField: "ReporterId", foreignKeyValue: "Reporter", dataSource: Reporters }, { field: "BranchLocation", headerText: "Branch" }, { field: "DateOfJoin", headerText: "Date Of Joined", type: "date", format: { type: "date", format: "MMM dd yyyy" }, editType: "datepickeredit", edit: { params: { format: "MMM dd yyyy" } } }, { field: "EmpStatus", headerText: "Status", editType: "dropdownedit", foreignKeyField: "EmpStatusId", foreignKeyValue: "EmpStatus", dataSource: StatusList } ], dataSource: gridDataSource, height: "auto", created: onCreated, allowPaging: true, pageSettings: { pageSize: 15 }, selectionSettings: { type: "Multiple", persistSelection: true } }); document.body.appendChild(ej.base.createElement("div", { id: "sample" })); gridInstance.appendTo("#sample"); } function onCreated(args) { //Enable multicolumn edit. try { // pass grid instance and Data-manager instance as parameters to enable column bulk-edit feature. enableBulkColumnEdit(this, gridDataSource); } catch (ex) { console.log("Refer Ej2GridExtendedFeature.js to enable Column bulk edit. InnerException "+ ex); } }
Note: Enabling the column bulk-edit feature will override the Context Menu event and selection setting of the grid.
In this section, we are going to see the implementation logic used in the script file Ej2GridExtendedFeature.js, which helps developers customize the column bulk-edit feature in JavaScript DataGrid if needed.
Create the edit dialog dynamically during the page rendering. This dialog will show the desired editor when right-clicking on the grid column.
Please find the logic in the create_InitializeEditModal() method in the Ej2GridExtendedFeature.js file.
Sample code
function create_InitializeEditModal() { var modalContainerEle = document.createElement("div"); modalContainerEle.id = "BulkEdit-dialog-container"; var modalEle = document.createElement("div"); modalEle.id = "dialogBulkEdit"; var inputContainerEle = document.createElement("div"); inputContainerEle.id = "modal-editor-container"; modalEle.appendChild(inputContainerEle); modalContainerEle.appendChild(modalEle); document.body.appendChild(modalContainerEle); editDialogInstance = new ej.popups.Dialog({ target: document.getElementById("BulkEdit-dialog-container"), width: '350px', showCloseIcon: true, position: { X: 'center', Y: 'center' }, visible: false, buttons: [ { 'click': onClickSaveBtn, buttonModel: { isPrimary: true, content: 'Save' } }, { 'click': onClickCancelBtn, buttonModel: { content: 'Cancel' } } ] }); // Render/initialized Dialog editDialogInstance.appendTo('#dialogBulkEdit'); modalEle.style.top = '100px'; }
Here we bind the customer gridRightClickHandler() to the contextmenu event of the grid.
Right-click on the DataGrid column, create the editor element dynamically, and append it to the bulk edit modal, based on the current column data type.
Please find the dynamic editor creation logic in the gridRightClickHandler() method definition.
Sample code
if (editColumnType === DATA_TYPE.STRING && editType === EDIT_TYPE.DROPDOWN_EDIT) { var dataSource = []; if (curRowInfo.column.dataSource) { dataSource = curRowInfo.column.dataSource; } inputEditorInstance = new ej.dropdowns.DropDownList({ placeholder: "Select " + editFieldName, popupHeight: "200px", dataSource: dataSource, fields: { text: currentEditColumn, value: currentEditColumn } }); } else if (editColumnType === DATA_TYPE.STRING) { inputEditorInstance = new ej.inputs.TextBox({ placeholder: editFieldName }); } else if (editColumnType === DATA_TYPE.DATE) { var format = "dd/MMM/yyyy"; if (curRowInfo.column.format && curRowInfo.column.format.format) { format = curRowInfo.column.format.format; } else if (curRowInfo.column.format) { format = curRowInfo.column.format; } inputEditorInstance = new ej.calendars.DatePicker({ format: format, placeholder: "Select " + editFieldName }); } else if (editColumnType === DATA_TYPE.NUMBER) { inputEditorInstance = new ej.inputs.NumericTextBox({ placeholder: editFieldName }); }
The editor will be displayed based on the column setting. Refer to the following table.
Column Setting | Result Screenshot |
Type: Numeric Example: gridInstance = new ej.grids.Grid({ columns: [ … { field: "PhoneNumber", headerText: "Phone", type: "number" }, … ] }); | Numeric text box will be displayed. |
Type: string Example: gridInstance = new ej.grids.Grid({ columns: [ … { field: "Name", headerText: "Employee Name", validationRules: { required: true } } … ] }); | Text box will be displayed. |
Note: If the type is not specified, then it will automatically set the first record value type as the column data type.
The bulk-edit dialog will always be created with form. If the current right-clicked column has a validation rule, then it will be added to the edit form. (If there is no validation rule, then the validation will not be applied.)
Please find the validation rule add logic in the gridRightClickHandler() method definition. Refer to the following sample code.
if (inputEditorInstance) { setTimeout(function () { inputEditorInstance.appendTo("#input-element"); /** * Add validation rule to edit modal input field */ if (curRowInfo.column.validationRules) { var validationOptions = { rules: {} }; validationOptions.rules[currentEditColumn] = curRowInfo.column.validationRules; formInstance = new ej.inputs.FormValidator('#' + editFormId, validationOptions); } // Edit dialog is displayed editDialogInstance.show(); }, 100); }
So, whenever you click on the Save button, the data will be validated (if form has any validation rule).
After successful form validation, the save object will be formatted for all the selected records and then saved using the DataManager instance.
Refer to the following code.
function onClickSaveBtn() { var editableRows = gridInstance.getSelectedRecords(); var changes = { changedRecords: [], addedRecords: [], deletedRecords: [] }; if ((formInstance && formInstance.validate()) || (formInstance === null)) { if (currentEditColumn) { for (var k = 0; k < editableRows.length; k++) { var updateObj = {}; var newValue = ""; newValue = inputEditorInstance.value; updateObj = editableRows[k]; updateObj[currentEditColumn] = newValue; changes.changedRecords.push(updateObj); } gridDataSource.saveChanges(changes, primaryKeyColumnField).then(e => { // Grid is refreshed with updated data gridInstance.refreshColumns(); }); // Previous changes are removed and dialog is hidden changes = { changedRecords: [], addedRecords: [], deletedRecords: [] }; currentEditColumn = ""; editDialogInstance.hide(); } } }
In this blog, the Ej2GridExtendedFeature.js file has support for the following grid column edit types:
Note: Please refer to Cell edit type and its params documentation.
You can download the demo video on our website.
For further reference, you can checkout Bulk Edit Columns in JavaScript DataGrid sample.
Follow these steps to run the sample:
In this blog, we have learned how to implement the column bulk edit feature in the Syncfusion JavaScript DataGrid. With this, you can easily update multiple cells in a column at once, which saves a lot of time and reduces your workload. I hope you found this blog useful. Try out the steps given in this blog and leave your feedback in the comments section below.
Syncfusion DataGrid is also available in the Blazor, ASP.NET (Core, MVC, WebForms), Angular, React , Vue, Xamarin, Flutter, UWP, WinForms, WPF, and WinUI platforms. For existing customers, the new version is available for download from the License and Downloads page. If you are not yet a Syncfusion customer, you can try our 30-day free trial to check out our available features.
For questions, you can contact us through our support forum, Direct-Trac, or feedback portal. We are always happy to assist you!
If you liked this blog post, we think you’ll also like the following articles: