Inline Editing in ASP.NET MVC Grid Component

7 Mar 202417 minutes to read

In Normal edit mode, when you start editing the currently selected record is changed to edit state. You can change the cell values and save edited data to the data source. To enable Normal edit, set the Mode of EditSettings as Normal.

@Html.EJS().Grid("InlineEdit").DataSource((IEnumerable<object>)ViewBag.DataSource).Columns(col =>
{
    col.Field("OrderID").HeaderText("Order ID").IsPrimaryKey(true).Width("120").ValidationRules(new { required = "true"}).TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).Add();
    col.Field("CustomerID").HeaderText("Customer Name").Width("150").ValidationRules(new { required = "true", minLength=3 }).Add();
    col.Field("Freight").HeaderText("Freight").Width("120").Format("C2").TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).Add();
    col.Field("ShipName").HeaderText("Ship Name").Width("150").Add();
    col.Field("ShipCountry").HeaderText("Ship Country").Width("150").Add();

}).AllowPaging().PageSettings(page => page.PageCount(2)).EditSettings(edit => { edit.AllowAdding(true).AllowEditing(true).AllowDeleting(true).Mode(Syncfusion.EJ2.Grids.EditMode.Normal); }).Toolbar(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" }).Render()
public IActionResult Index()
{
    var Order = OrderDetails.GetAllRecords();
    ViewBag.DataSource = Order;
    return View();
}

NOTE

Normal edit mode is default mode of editing.

Automatically update the column based on another column edited value

You can update the column value based on another column edited value 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.

@Html.EJS().Grid("Grid").DataSource((IEnumerable<object>)ViewBag.DataSource).Columns(col =>
   {
       col.Field("ProductID").HeaderText("Product ID").IsPrimaryKey(true).Width("120").TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).Add();
       col.Field("ProductName").HeaderText("Product Name").Width("150").Add();
       col.Field("UnitPrice").HeaderText("Unit Price").Width("150").EditType("numericedit").Edit(new {create = "priceCreate", read = "priceRead", destroy = "priceDestroy", write = "priceWrite"}).Format("C2").TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).Add();
       col.Field("UnitsInStock").HeaderText("Units In Stock").Width("150").EditType("numericedit").Edit(new {create = "stockCreate", read = "stockRead", destroy = "stockDestroy", write = "stockWrite"}).TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).Add();
       col.Field("TotalCost").HeaderText("Total Cost").Width("150").AllowEditing(false).Format("C2").TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).Add();
   }).EditSettings(edit => { edit.AllowAdding(true).AllowEditing(true).AllowDeleting(true).Mode(Syncfusion.EJ2.Grids.EditMode.Normal); }).Toolbar(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" }).Render()


<script>
   var priceElem;
    var priceObj;

    var stockElem;
    var stockObj;

    function priceCreate(args) {
        priceElem = document.createElement('input');
        return priceElem;
    }

    function priceWrite(args) {

        priceObj = new ej.inputs.NumericTextBox({
            value: args.rowData[args.column.field],
            change: function (args) {
                var formEle = document.getElementById("Grid").querySelector("form").ej2_instances[0];
                var totalCostFieldEle = formEle.getInputElement('TotalCost');
                totalCostFieldEle.value = priceObj.value * stockObj.value;
            }
        });
        priceObj.appendTo(priceElem);
    }

    function priceDestroy() {
        priceObj.destroy();
    }

    function priceRead(args) {
        return priceObj.value;
    }
    
    function stockCreate(args) {
        stockElem = document.createElement('input');
        return stockElem;
    }

    function stockWrite(args) {

        stockObj = new ej.inputs.NumericTextBox({
            value: args.rowData[args.column.field],
            change: function (args) {
                var formEle = document.getElementById("Grid").querySelector("form").ej2_instances[0];
                var totalCostFieldEle = formEle.getInputElement('TotalCost');
                totalCostFieldEle.value = priceObj.value * stockObj.value;
            }
        });
        stockObj.appendTo(stockElem);
    }

    function stockDestroy() {
        stockObj.destroy();
    }

    function stockRead(args) {
        return stockObj.value;
    }
   
</script>
public IActionResult Index()
{
    var Order = OrderDetails.GetAllRecords();
    ViewBag.DataSource = Order;
    return View();
}

Cancel edit based on condition

You can prevent the CRUD operations of the Grid by using condition in the actionBegin event with requestType as beginEdit for editing, add for adding and delete for deleting actions.

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.

<button onclick="btnClick(event)">Grid is Addable</button>
@Html.EJS().Grid("InlineEdit").DataSource((IEnumerable<object>)ViewBag.DataSource).Columns(col =>
{
    col.Field("OrderID").HeaderText("Order ID").IsPrimaryKey(true).Width("120").ValidationRules(new { required = "true"}).TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).Add();
    col.Field("Role").HeaderText("Role").Width("150").ValidationRules(new { required = "true" }).Add();
    col.Field("Freight").HeaderText("Freight").Width("120").Format("C2").TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).Add();
    col.Field("ShipName").HeaderText("Ship Name").Width("150").Add();
    col.Field("ShipCountry").HeaderText("Ship Country").Width("150").Add();

}).ActionBegin("actionBegin").AllowPaging().PageSettings(page => page.PageCount(2)).EditSettings(edit => { edit.AllowAdding(true).AllowEditing(true).AllowDeleting(true).Mode(Syncfusion.EJ2.Grids.EditMode.Normal); }).Toolbar(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" }).Render()

<script>
    var isAddable = true;
    function actionBegin(args) {
        if (args.requestType == 'beginEdit') {
            if (args.rowData['Role'].toLowerCase() == 'employee') {
                args.cancel = true;
            }
        }
        if (args.requestType == 'delete') {
            if (args.data[0]['Role'].toLowerCase() == 'employee') {
                args.cancel = true;
            }
        }
        if (args.requestType == 'add') {
            if (!isAddable) {
                args.cancel = true;
            }
        }
    }

    function btnClick(args) {
        args.target.innerText == 'Grid is Addable' ? (args.target.innerText = 'Grid is Not Addable') : (args.target.innerText = 'Grid is Addable');
        isAddable = !isAddable;
    }
</script>
public IActionResult Index()
{
    var Order = OrderDetails.GetAllRecords();
    ViewBag.DataSource = Order;
    return View();
}

Perform CRUD action programmatically

Grid methods can be used to perform CRUD operations programmatically. The addRecord, deleteRecord, and startEdit methods are used to perform CRUD operations in the following demo.

  • To add a new record to the Grid, use the addRecord method. In this method, you can pass the data parameter to add a new record to the Grid, and the index parameter to add a record at a specific index. If you call this method with no parameters, it will create an empty row in the Grid.

  • To change the selected row to the edit state, use the startEdit method.

  • If you need to update the row data in the Grid’s datasource, you can use the updateRow method. In this method, you need to pass the index value of the row to be updated along with the updated data.

  • If you need to update the particular cell in the row, you can use the setCellValue method. In this method, you need to pass the primary key value of the data source, field name, and new value for the particular cell.

  • To remove a selected row from the Grid, use the deleteRecord method. For both edit and delete operations, you must select a row first.

NOTE

In both normal and dialog editing modes, these methods can be used.

@Html.EJS().Button("add").Content("Add").IsPrimary(true).Render()
@Html.EJS().Button("edit").Content("Edit").IsPrimary(true).Render()
@Html.EJS().Button("delete").Content("Delete").IsPrimary(true).Render()
@Html.EJS().Button("updaterow").Content("Update Row").IsPrimary(true).Render()
@Html.EJS().Button("updatecell").Content("Update Cell").IsPrimary(true).Render()

@Html.EJS().Grid("Grid").DataSource((IEnumerable<object>)ViewBag.dataSource).Columns(col =>
{

    col.Field("OrderID").HeaderText("Order ID").Width("120").IsPrimaryKey(true).TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).Add();
    col.Field("CustomerID").HeaderText("Customer Name").Width("170").Add();
    col.Field("OrderDate").HeaderText("Order Date").Width("130").Format("yMd").TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).Add();
    col.Field("Freight").HeaderText("Freight").Width("120").Format("C2").TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).Add();

}).EditSettings(edit => { edit.AllowAdding(true).AllowEditing(true).AllowDeleting(true); }).Render()

<script>
    document.getElementById('add').onclick = function () {
        document.getElementById('Grid').ej2_instances[0].addRecord({ "OrderID": "10001", "CustomerID": "ENTR", "OrderDate": "4/4/1998", "Freight": "250.9" });
    }

    document.getElementById('edit').onclick = function () {
        document.getElementById('Grid').ej2_instances[0].startEdit();
    }

    document.getElementById('delete').onclick = function () {
        document.getElementById('Grid').ej2_instances[0].deleteRecord();
    }

    document.getElementById('updaterow').onclick = function () {
        document.getElementById('Grid').ej2_instances[0].updateRow(0, { OrderID: 10001, CustomerID: "ENTR", OrderDate: '4/4/1998', Freight: '250.9' });
    }

    document.getElementById('updatecell').onclick = function () {
        document.getElementById('Grid').ej2_instances[0].setCellValue(document.getElementById('Grid').ej2_instances[0].currentViewData[0].OrderID, 'CustomerID', 'Value Changed');
    }
</script>
public IActionResult Index()
{
    var Order = OrderDetails.GetAllRecords();
    ViewBag.DataSource = Order;
    return View();
}

Confirmation dialog

The delete confirm dialog can be shown when deleting a record by defining the ShowDeleteConfirmDialog as true.

@Html.EJS().Grid("Grid").DataSource((IEnumerable<object>)ViewBag.DataSource).Columns(col =>
{
   col.Field("OrderID").HeaderText("Order ID").IsPrimaryKey(true).Width("120").TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).ValidationRules(new { required = "true"}).Add();
   col.Field("CustomerID").HeaderText("Customer Name").Width("150").ValidationRules(new { required = "true", minLength = 3 }).Add();
   col.Field("Freight").HeaderText("Freight").Width("120").EditType("numericedit").Format("C2").TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).Add();
   col.Field("ShipName").HeaderText("Ship Name").Width("150").Add();
   col.Field("ShipCountry").HeaderText("Ship Country").EditType("dropdownedit").Width("150").Add();

}).AllowPaging().EditSettings(edit => { edit.AllowAdding(true).AllowEditing(true).AllowDeleting(true).ShowDeleteConfirmDialog(true); }).Toolbar(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" }).Render()
public IActionResult Index()
 {
   var orders = OrderDetails.GetAllRecords();
   ViewBag.DataSource = orders;            
   return View();
 }

NOTE

The ShowDeleteConfirmDialog supports all type of edit modes.

Default column values on add new row

The grid provides an option to set the default value for the columns when adding a new record in it. To set a default value for the particular column by defining the DefaultValue of Column.

@Html.EJS().Grid("DefaultValue").DataSource((IEnumerable<object>)ViewBag.DataSource).Columns(col =>
{
   col.Field("OrderID").HeaderText("Order ID").IsPrimaryKey(true).Width("120").ValidationRules(new { required = "true" }).TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).Add();
   col.Field("CustomerID").HeaderText("Customer Name").Width("150").ValidationRules(new { required = "true", minLength = 3 }).DefaultValue("HANAR").Add();
   col.Field("Freight").HeaderText("Freight").Width("120").Format("C2").TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).Add();
   col.Field("ShipName").HeaderText("Ship Name").Width("150").Add();
   col.Field("ShipCountry").HeaderText("Ship Country").Width("150").Add();

}).AllowPaging().EditSettings(edit => { edit.AllowAdding(true).AllowEditing(true).AllowDeleting(true).Mode(Syncfusion.EJ2.Grids.EditMode.Normal); }).Toolbar(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" }).Render()
public IActionResult Index()
 {
   var orders= OrderDetails.GetAllRecords();
   ViewBag.DataSource = orders;            
   return View();
 }

Adding a new row at the bottom of the Grid

By default, a new row will be added at the top of the grid. You can change it by setting NewRowPosition of EditSettings as Bottom.

@Html.EJS().Grid("EditToolbar").DataSource((IEnumerable<object>)ViewBag.DataSource).Columns(col =>
{
   col.Field("OrderID").HeaderText("Order ID").IsPrimaryKey(true).Width("120").TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).ValidationRules(new { required = "true"}).Add();
   col.Field("CustomerID").HeaderText("Customer Name").Width("150").ValidationRules(new { required = "true", minLength = 3 }).Add();
   col.Field("Freight").HeaderText("Freight").Width("120").Format("C2").TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).Add();
   col.Field("ShipName").HeaderText("Ship Name").Width("150").Add();
   col.Field("ShipCountry").HeaderText("Ship Country").Width("150").Add();

}).AllowPaging().EditSettings(edit => { edit.AllowAdding(true).AllowEditing(true).AllowDeleting(true).NewRowPosition(Syncfusion.EJ2.Grids.NewRowPosition.Bottom).Mode(Syncfusion.EJ2.Grids.EditMode.Normal); }).Toolbar(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" }).Render()
public IActionResult Index()
{
    var Order = OrderDetails.GetAllRecords();
    ViewBag.DataSource = Order;
    return View();
}

NOTE

Add newRowPostion is supported for Normal and Batch editing modes.

Show add new row always in grid

The Syncfusion Grid simplifies the addition of new records by consistently presenting a blank, “add new row” form within the grid. To enable this feature, you can set the ShowAddNewRow property within the EditSettings configuration to true. This allows for continuous addition of new records. You can display the add a new row at either the top or bottom of the grid content, depending on the NewRowPosition property of EditSettings. By default, the add new row is displayed at the top row of the grid content.

The following sample demonstrates how to add a new record continuously using ShowAddNewRow property.

@Html.EJS().Grid("ShowAddNewRow").DataSource((IEnumerable<object>)ViewBag.DataSource).Columns(col =>
{
    col.Field("OrderID").HeaderText("Order ID").IsPrimaryKey(true).Width("120").ValidationRules(new { required = "true"}).TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).Add();
    col.Field("CustomerID").HeaderText("Customer Name").Width("150").ValidationRules(new { required = "true", minLength=5 }).Add();
    col.Field("Freight").HeaderText("Freight").Width("120").Format("C2").TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).EditType("numericedit").ValidationRules(new { required = "true", min=1 }).Add();
    col.Field("ShipName").HeaderText("Ship Name").Width("150").Add();
    col.Field("ShipCountry").HeaderText("Ship Country").Width("150").EditType("dropdownedit").Add();

}).AllowPaging().PageSettings(page => page.PageCount(2)).EditSettings(edit => { edit.AllowAdding(true).AllowEditing(true).AllowDeleting(true).NewRowPosition(Syncfusion.EJ2.Grids.NewRowPosition.TOP).ShowAddNewRow(true); }).Toolbar(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" }).Render()
public IActionResult Index()
{
    var Order = OrderDetails.GetAllRecords();
    ViewBag.DataSource = Order;
    return View();
}

To save the newly added records, you can either hit the Enter key or click on the Update button located on the toolbar after filling in the new add form.

Limitations

  • This feature is supported only for Inline/Normal editing mode and is not compatible with other edit modes.
  • The new blank add row form will always be displayed at the top, even if you have set the new row position as the bottom for Virtual Scrolling and Infinite Scrolling enabled grid.
  • This feature is not compatible with the column virtualization feature.

Move the focus to a particular cell instead of first cell while editing a row

The RecordDoubleClick event allows you to move the focus to the corresponding cell (the cell that you doubled-clicked to edit a row) instead of the first cell in edit form. With the help of this event, you can focus the double-clicked column in inline edit mode.

@Html.EJS().Grid("Grid").DataSource((IEnumerable<object>)ViewBag.DataSource).EditSettings(edit => { edit.AllowAdding(true).AllowEditing(true).AllowDeleting(true).Mode(Syncfusion.EJ2.Grids.EditMode.Normal); }).Columns(col =>
{
   col.Field("OrderID").HeaderText("Order ID").TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).Width("120").Add();
   col.Field("CustomerID").HeaderText("Customer Name").Width("150").Add();
    col.Field("Freight").HeaderText("Freight").Width("120").Format("C2").TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).Add();
   col.Field("ShipCity").HeaderText("Ship City").Width("120").Add();
   col.Field("ShipCountry").HeaderText("Ship Country").Width("150").Add();

}).AllowPaging().RecordDoubleClick("recordDoubleClick").ActionComplete("ActionComplete").Toolbar(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" }).Render()

<script>
var fieldName;
function recordDoubleClick(e) {
  var clickedColumnIndex = e.cell.getAttribute("aria-colindex");
  fieldName = this.columnModel[parseInt(clickedColumnIndex)].field;
}

function actionComplete(e) {
  if (e.requestType === "beginEdit") {
    // focus the column
    e.form.elements[grid.element.getAttribute("id") + fieldName].focus();
  }
}
</script>
public IActionResult Index()
{
    var Order = OrderDetails.GetAllRecords();
    ViewBag.DataSource = Order;
    return View();
}