Search results

Editing in ASP.NET MVC Grid control

26 Nov 2021 / 13 minutes to read

The Grid component has options to dynamically insert, delete and update records. Editing feature requires a primary key column for CRUD operations. To define the primary key, set IsPrimaryKey property of Column to true in particular column.

You can start the edit action either by double clicking the particular row or by selecting the required row and click on Edit button in the toolbar. Similarly, you can add a new record to grid either by clicking on Add button in the toolbar or on an external button which is bound to invoke the addRecord method of the grid, Save and Cancel while in edit mode is possible using respective toolbar icon in grid.

Deletion of the record is possible by selecting the required row and click on Delete button in the toolbar.

razor
edit.cs
Copied to clipboard
@Html.EJS().Grid("NormalEdit").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()
Copied to clipboard
public IActionResult Index()
{
    var Order = OrderDetails.GetAllRecords();
    ViewBag.DataSource = Order;
    return View();
}

If IsIdentity is enabled, then it will be considered as a read-only column when editing and adding a record. You can disable editing for a particular column, by specifying AllowEditing to false.

Toolbar with edit option

The grid toolbar has the built-in items to execute Editing actions. You can define this by using the Toolbar property.

razor
edittoolbar.cs
Copied to clipboard
@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).Mode(Syncfusion.EJ2.Grids.EditMode.Normal); }).Toolbar(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" }).Render()
Copied to clipboard
public IActionResult Index()
{
    var Order = OrderDetails.GetAllRecords();
    ViewBag.DataSource = Order;
    return View();
}

Cell edit type and its params

The EditType of Column is used to define the editor component for any particular column.

You can set the EditType based on data type of the column.

  • NumericTextBox component for integers, double, and decimal data types.
  • TextBox component for string data type.
  • DropDownList component to show all unique values related to that field.
  • CheckBox component for boolean data type.
  • DatePicker component for date data type.
  • DateTimePicker component for date time data type.

Also, you can customize the behavior of the editor component through Params of Edit property in Column.

The following table describes cell edit type and their corresponding edit params of the column.

Component Example
NumericTextBox params: { decimals: 2, value: 5 }
DropDownList params: { value: ‘Germany’ }
Checkbox params: { checked: true}
DatePicker params: { format:‘dd.MM.yyyy’ }
DateTimePicker params: { value: new Date() }
razor
celleditparams.cs
Copied to clipboard
@Html.EJS().Grid("EditParam").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").EditType("numericedit").Format("C2").TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).Edit(new { @params = new { decimals = 2, value = 5} }).Add();
    col.Field("ShipCountry").HeaderText("Ship Country").EditType("dropdownedit").Edit(new { @params = new { value = "Germany" } }).Width("150").Add();
    col.Field("OrderDate").HeaderText("Order Date").EditType("datepickeredit").Edit(new { @params = new { value = new Date() } }).Width("150").Add();
    col.Field("Verified").HeaderText("Verified").EditType("booleanedit").Edit(new { @params = new { checked = true } }).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()
Copied to clipboard
public IActionResult Index()
 {
   var orders = OrdersDetails.GetAllRecords();
   ViewBag.datasource = orders;            
   return View();
 }

If edit type is not defined in the column, then it will be considered as the stringedit type (Textbox component) .

Cell Edit Template

The cell edit template is used to add a custom component for a particular column by invoking the following functions:

  • create - It is used to create the element at the time of initialization.
  • write - It is used to create the custom component or assign default value at the time of editing.
  • read - It is used to read the value from the component at the time of save.
  • destroy - It is used to destroy the component.
razor
celledittemplate.cs
Copied to clipboard
@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").Format("C2").TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).Add();
    col.Field("OrderDate").HeaderText("Ship Name").Format("yMd").Edit(new { create = "create", read = "read", destroy = "destroy", write = "write" }).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()

<script>
    var elem;
    var dObj;
    function create(args) {
        elem = document.createElement('input');
        return elem;
    }
    function write(args) {
        dObj = new ej.calendars.DatePicker({
            value: new Date(args.rowData[args.column.field]),
            placeholder: 'Select DateTime'
        });
        dObj.appendTo(elem);
    }

    function destroy() {
        dObj.destroy();
    }
    function read(args) {
        return dObj.value;
    }
</script>
Copied to clipboard
public IActionResult Index()
 {
   var orders = OrdersDetails.GetAllRecords();
   ViewBag.datasource = orders;            
   return View();
 }

Edit Modes

Grid supports the following types of edit modes, they are:

  • Normal
  • Dialog
  • Batch

Normal

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.

razor
inline.cs
Copied to clipboard
@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()
Copied to clipboard
public IActionResult Index()
{
    var Order = OrderDetails.GetAllRecords();
    ViewBag.DataSource = Order;
    return View();
}

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.

razor
autoupdate.cs
Copied to clipboard
@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>
Copied to clipboard
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.

razor
canceleditinline.cs
Copied to clipboard
<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>
Copied to clipboard
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.

razor
programmatic.cs
Copied to clipboard
@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>
Copied to clipboard
public IActionResult Index()
{
    var Order = OrderDetails.GetAllRecords();
    ViewBag.DataSource = Order;
    return View();
}

Dialog

In dialog edit mode, when you start editing the currently selected row data will be shown on a dialog. You can change the cell values and save edited data to the data source. To enable Dialog edit, set the Mode of EditSettings as Dialog.

razor
dialog.cs
Copied to clipboard
@Html.EJS().Grid("DialogEdit").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.Dialog); }).Toolbar(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" }).Render()
Copied to clipboard
public IActionResult Index()
{
    var Order = OrderDetails.GetAllRecords();
    ViewBag.DataSource = Order;
    return View();
}

Batch

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 calling the batchSave method. To enable Batch edit, set the Mode of EditSettings as Batch.

razor
batch.cs
Copied to clipboard
@Html.EJS().Grid("BatchEdit").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.Batch); }).Toolbar(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" }).Render()
Copied to clipboard
public IActionResult Index()
{
    var Order = OrderDetails.GetAllRecords();
    ViewBag.DataSource = Order;
    return View();
}

Cancel edit based on condition in Batch mode

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.

razor
canceleditbatch.cs
Copied to clipboard
<button onclick="btnClick(event)">Grid is Addable</button>
@Html.EJS().Grid("BatchEdit").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").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();

}).CellEdit("cellEdit").BeforeBatchAdd("beforeBatchAdd").BeforeBatchDelete("beforeBatchDelete").AllowPaging().PageSettings(page => page.PageCount(2)).EditSettings(edit => { edit.AllowAdding(true).AllowEditing(true).AllowDeleting(true).Mode(Syncfusion.EJ2.Grids.EditMode.Batch); }).Toolbar(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" }).Render()

<script>
    var isAddable = 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;
    }

    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;
        }
    }

</script>
Copied to clipboard
public IActionResult Index()
{
    var Order = OrderDetails.GetAllRecords();
    ViewBag.DataSource = Order;
    return View();
}

Dialog/Inline template

The dialog template editing provides an option to customize the default behavior of dialog editing. Using the dialog template, you can render your own editors by defining the Mode of EditSettings as Dialog/Inline and Template as SCRIPT element ID or HTML string which holds the template.

In some cases, you need to add the new field editors in the dialog which are not present in the column model. In that situation, the template will help you to customize the default edit dialog.

In the below code example, demonstrate the usage of binding a partial view in the dialog template.

razor
dialog.cs
Copied to clipboard
@Html.EJS().Grid("DialogTemplateEdit").DataSource((IEnumerable<object>)ViewBag.DataSource).ActionComplete("actionComplete").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").Add();
    col.Field("ShipCountry").HeaderText("Ship Country").EditType("dropdownedit").Width("150").Add();

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


<script>
   function actionComplete(args) {
       if (args.requestType === 'beginEdit') {
          var ajax = new ej.base.Ajax({
            url: "/Home/Editpartial", //render the partial view
            type: "POST",
            contentType: "application/json",
            data: JSON.stringify({ value: args.rowData })
          });
          ajax.send().then(function (data) {
            $("#dialogTemp").html(data); //Render the edit form with selected record
                args.form.elements.namedItem('CustomerID').focus();
            }).catch(function (xhr) {
                console.log(xhr);
            });
          }
       if (args.requestType === 'add') {
             var ajax = new ej.base.Ajax({
                url: "/Home/Addpartial", //render the partial view
                type: "POST",
                contentType: "application/json",
             });
             ajax.send().then(function (data) {
                $("#dialogTemp").html(data); //Render the edit form with selected record
                    args.form.elements.namedItem('OrderID').focus();
                }).catch(function (xhr) {
                    console.log(xhr);
                });
        }
   }
</script>

<script id='dialogtemplate' type="text/x-template">
    <div id="dialogTemp">
    </div>
</script>
Copied to clipboard
public IActionResult Index()
{
    var Order = OrderDetails.GetAllRecords();
    ViewBag.DataSource = Order;
    return View();
} 

public ActionResult Editpartial(DialogTemplateModel value)
{
    var order = OrdersDetails.GetAllRecords();
    ViewBag.datasource = order;
    return PartialView("Editpartial", value);
}

public ActionResult AddPartial()
{
    var order = OrdersDetails.GetAllRecords();
    ViewBag.datasource = order;
    return PartialView("Addpartial");
}

The Dialog/Inline template form editors should have name attribute.

Reading Values From Editors

You can read, format and update the current editor value in the ActionBeginevent at the time of requestType as save.

In the below code example, we have format and updated the freight value.

Copied to clipboard
function actionBegin(args) {
    if (args.requestType === 'save') {
        // cast string to integer value.
        args.data['Freight'] = parseFloat(args.form.querySelector("#Freight").value);
    }
}

Set focus to editor

By default, the first input element in the dialog will be focused while opening the dialog. If the first input element is in disabled or hidden state, focus the valid input element in the ActionComplete event based on requestType as beginEdit.

Copied to clipboard
function actionComplete(args) {
    // Set initail Focus
    if (args.requestType === 'beginEdit') {
        (args.form.elements.namedItem('CustomerID')).focus();
    }
}

Adding validation rules for custom editors

If you have used additional fields that are not present in the column model, then add the validation rules to the ActionComplete event.

Copied to clipboard
function actionComplete(args) => {
    if ((args.requestType === 'beginEdit' || args.requestType === 'add')) {
        // Add Validation Rules
        args.form.ej2_instances[0].addRules('Freight', {max: 500});
    }
}

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.

razor
rowposition.cs
Copied to clipboard
@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()
Copied to clipboard
public IActionResult Index()
{
    var Order = OrderDetails.GetAllRecords();
    ViewBag.DataSource = Order;
    return View();
}

Add newRowPostion is supported for Normal and Batch editing modes.

Command column

The command column provides an option to add CRUD action buttons in a column. This can be defined by the Commands property of Column.

The available built-in command buttons are:

Command Button Actions
Edit Edit the current row.
Delete Delete the current row.
Save Update the edited row.
Cancel Cancel the edited state.
razor
commandcolumn.cs
Copied to clipboard
@{
    List<object> commands = new List<object>();
    commands.Add(new { type = "Edit", buttonOption = new { iconCss = "e-icons e-edit", cssClass = "e-flat" } });
    commands.Add(new { type = "Delete", buttonOption = new { iconCss = "e-icons e-delete", cssClass = "e-flat" } });
    commands.Add(new { type = "Save", buttonOption = new { iconCss = "e-icons e-update", cssClass = "e-flat" } });
    commands.Add(new { type = "Cancel", buttonOption = new { iconCss = "e-icons e-cancel-icon", cssClass = "e-flat" } });
}

@Html.EJS().Grid("CommandColumn").DataSource((IEnumerable<object>)ViewBag.DataSource).Columns(col =>
{
  col.Field("OrderID").HeaderText("Order ID").IsPrimaryKey(true).Width("120").TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).Add();
  col.Field("CustomerID").HeaderText("Customer Name").Width("150").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();
  col.HeaderText("Manage Records").Width("160").Commands(commands).Add();

}).AllowPaging().EditSettings(edit => { edit.AllowAdding(true).AllowEditing(true).AllowDeleting(true); }).Render()
Copied to clipboard
public IActionResult Index()
 {
   var orders= OrderDetails.GetAllRecords();
   ViewBag.DataSource = orders;            
   return View();
 }

Custom command

The custom command buttons can be added in a column by using the Commands property of Column and the action for the custom buttons can be defined using commandClick event.

razor
customcommand.cs
Copied to clipboard
@{
    List<object> commands = new List<object>();
    commands.Add(new { type = "userstatus", buttonOption = new { content = "Details", cssClass = "e-flat" } });
}

@Html.EJS().Grid("CustomCommand").DataSource((IEnumerable<object>)ViewBag.DataSource).Columns(col =>
{
    col.Field("OrderID").HeaderText("Order ID").IsPrimaryKey(true).Width("120").TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).Add();
    col.Field("CustomerID").HeaderText("Customer Name").Width("150").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();
    col.HeaderText("Commands").Width("160").Commands(commands).Add();

}).AllowPaging().CommandClick("commandClick").EditSettings(edit => { edit.AllowAdding(true).AllowEditing(true).AllowDeleting(true); }).Render()

<script>
    function commandClick(args) {
            alert(JSON.stringify(args.rowData));  // display row data
        }
    }
</script>
Copied to clipboard
public IActionResult Index()
 {
   var orders = OrdersDetails.GetAllRecords();
   ViewBag.DataSource = orders;            
   return View();
 }

Confirmation messages

Delete confirmation

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

razor
deleteconfirm.cs
Copied to clipboard
@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()
Copied to clipboard
public IActionResult Index()
 {
   var orders = OrderDetails.GetAllRecords();
   ViewBag.DataSource = orders;            
   return View();
 }

The ShowDeleteConfirmDialog supports all type of edit modes.

Batch confirmation

By default, grid will show the confirm dialog when saving or cancelling or performing any actions like filtering, sorting, etc.

razor
batchconfirm.cs
Copied to clipboard
@Html.EJS().Grid("Grid").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").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().PageSettings(page => page.PageCount(5)).Toolbar(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" }).EditSettings(edit => { edit.AllowAdding(true).AllowEditing(true).AllowDeleting(true).ShowConfirmDialog(false).ShowDeleteConfirmDialog(true).Mode(Syncfusion.EJ2.Grids.EditMode.Batch); }).Render()
Copied to clipboard
public IActionResult Index()
{
    var Order = OrderDetails.GetAllRecords();
    ViewBag.DataSource = Order;
    return View();
}

ShowConfirmDialog of EditSettingsrequires the Mode to be Batch. If ShowConfirmDialog set to false, then confirmation dialog does not display in batch editing.

Column validation

Column validation allows you to validate the edited or added row data and it display errors for invalid fields before saving data. Grid uses Form Validator component for column validation. You can set validation rules by defining the ValidationRules.

razor
columnvalid.cs
Copied to clipboard
@Html.EJS().Grid("Validation").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()
Copied to clipboard
public IActionResult Index()
 {
   var orders = OrderDetails.GetAllRecords();
   ViewBag.DataSource = orders;            
   return View();
 }

Persisting data in server

Edited data can be persisted in the database using the RESTful web services.

All the CRUD operations in the grid are done through DataManager. The DataManager has an option to bind all the CRUD related data in server-side.

For your information, the ODataAdaptor persists data in the server as per OData protocol.

In the below section, we have explained how to get the edited data details on the server-side using the UrlAdaptor.

URL adaptor

You can use the UrlAdaptor of DataManager when binding data source from remote data. In the initial load of grid, data are fetched from remote data and bound to the grid using url property of DataManager. You can map The CRUD operation in grid can be mapped to server-side Controller actions using the properties InsertUrl, RemoveUrl, UpdateUrl, CrudUrl and BatchUrl.

The following code example describes the above behavior.

razor
urladaptorMVC.cs
Copied to clipboard
@Html.EJS().Grid("CommandColumn").DataSource(dataManager => { dataManager.Url("/Home/UrlDatasource").InsertUrl("/Home/Insert").UpdateUrl("/Home/Update").RemoveUrl("/Home/Delete").Adaptor("UrlAdaptor"); }).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").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); }).Toolbar(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" }).Render()
Copied to clipboard
public ActionResult UrlDatasource(DataManagerRequest dm)
{
  IEnumerable DataSource = OrdersDetails.GetAllRecords();
  DataOperations operation = new DataOperations();
  int count = DataSource.Cast<OrdersDetails>().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);
}

Also, when using the UrlAdaptor, you need to return the data as JSON from the controller action and the JSON object must contain a property as result with dataSource as its value and one more property count with the dataSource total records count as its value.

The following code example describes the above behavior.

razor
urladaptorMVC.cs
Copied to clipboard
@Html.EJS().Grid("CommandColumn").DataSource(dataManager => { dataManager.Url("/Home/UrlDatasource").InsertUrl("/Home/Insert").UpdateUrl("/Home/Update").RemoveUrl("/Home/Delete").Adaptor("UrlAdaptor"); }).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").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); }).Toolbar(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" }).Render()
Copied to clipboard
public ActionResult UrlDatasource(DataManagerRequest dm)
{
  IEnumerable DataSource = OrdersDetails.GetAllRecords();
  DataOperations operation = new DataOperations();
  int count = DataSource.Cast<OrdersDetails>().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);
}

Insert record

Using the InsertUrl property, you can specify the controller action mapping URL to perform insert operation on the server-side.

The following code example describes the above behavior.

razor
insertMVC.cs
Copied to clipboard
@Html.EJS().Grid("CommandColumn").DataSource(dataManager => { dataManager.Url("/Home/UrlDatasource").InsertUrl("/Home/Insert").UpdateUrl("/Home/Update").RemoveUrl("/Home/Delete").Adaptor("UrlAdaptor"); }).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").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); }).Toolbar(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" }).Render()
Copied to clipboard
public ActionResult Insert(CRUDModel Object)
{
    var ord = Object.Value;
    OrdersDetails.GetAllRecords().Insert(0, ord);
    return Json(Object.Value);
}

public class CRUDModel
{
    public List<OrdersDetails> Added { get; set; }

    public List<OrdersDetails> Changed { get; set; }

    public List<OrdersDetails> Deleted { get; set; }

    public OrdersDetails Value { get; set; }

    public int key { get; set; }
    
    public string action { get; set; }
}

The newly added record details are bound to the Object parameter. Please refer to the following screenshot.

insert

Update record

Using the UpdateUrl property, the controller action mapping URL can be specified to perform save/update operation on the server-side.

The following code example describes the previous behavior.

razor
update.cs
Copied to clipboard
@Html.EJS().Grid("CommandColumn").DataSource(dataManager => { dataManager.Url("/Home/UrlDatasource").InsertUrl("/Home/Insert").UpdateUrl("/Home/Update").RemoveUrl("/Home/Delete").Adaptor("UrlAdaptor"); }).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").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); }).Toolbar(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" }).Render()
Copied to clipboard
public ActionResult Update([FromBody]ICRUDModel<OrdersDetails> value)
{
    var ord = value.value;
    OrdersDetails val = OrdersDetails.GetAllRecords().Where(or => or.OrderID == ord.OrderID).FirstOrDefault();
    val.OrderID = ord.OrderID;
    val.EmployeeID = ord.EmployeeID;
    val.CustomerID = ord.CustomerID;
    val.Freight = ord.Freight;
    val.OrderDate = ord.OrderDate;
    val.ShipCity = ord.ShipCity;

    return Json(value.value);
}

public class ICRUDModel<T> where T : class
{
    public string action { get; set; }

    public string table { get; set; }

    public string keyColumn { get; set; }

    public object key { get; set; }

    public T value { get; set; }

    public List<T> added { get; set; }

    public List<T> changed { get; set; }

    public List<T> deleted { get; set; }

    public IDictionary<string, object> @params { get; set; }
}

The updated record details are bound to the Object parameter. Please refer to the following screenshot.

update

Delete record

Using the RemoveUrl property, the controller action mapping URL can be specified to perform delete operation on the server-side.

The following code example describes the previous behavior.

razor
delete.cs
Copied to clipboard
@Html.EJS().Grid("CommandColumn").DataSource(dataManager => { dataManager.Url("/Home/UrlDatasource").InsertUrl("/Home/Insert").UpdateUrl("/Home/Update").RemoveUrl("/Home/Delete").Adaptor("UrlAdaptor"); }).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").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); }).Toolbar(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" }).Render()
Copied to clipboard
public ActionResult Delete([FromBody]ICRUDModel<OrdersDetails> value)
{
    OrdersDetails.GetAllRecords().Remove(OrdersDetails.GetAllRecords().Where(or => or.OrderID == int.Parse(value.key.ToString())).FirstOrDefault());
    return Json(value);
}

public class ICRUDModel<T> where T : class
{
    public string action { get; set; }

    public string table { get; set; }

    public string keyColumn { get; set; }

    public object key { get; set; }

    public T value { get; set; }

    public List<T> added { get; set; }

    public List<T> changed { get; set; }

    public List<T> deleted { get; set; }

    public IDictionary<string, object> @params { get; set; }
}

The deleted record primary key value is bound to the key parameter. Please refer to the following screenshot.

delete

CRUD URL

Using the CrudUrl property, the controller action mapping URL can be specified to perform all the CRUD operation at server-side using a single method instead of specifying separate controller action method for CRUD (insert, update and delete) operations.

The action parameter of CrudUrl is used to get the corresponding CRUD action.

The following code example describes the above behavior.

razor
crudurl.cs
Copied to clipboard
@Html.EJS().Grid("CrudUrl").DataSource(dataManager => { dataManager.Url("/Grid/UrlDatasource").CrudUrl("/Grid/CrudUpdate").Adaptor("UrlAdaptor"); }).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").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); }).Render()
Copied to clipboard
public IActionResult UrlDatasource([FromBody]DataManagerRequest dm)
{
    IEnumerable DataSource = OrdersDetails.GetAllRecords();
    DataOperations operation = new DataOperations();
    int count = DataSource.Cast<OrdersDetails>().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);
}

public ActionResult CrudUpdate([FromBody]ICRUDModel<OrdersDetails> value, string action)
{
    if (value.action == "update")
    {
        var ord = value.value;
        OrdersDetails val = OrdersDetails.GetAllRecords().Where(or => or.OrderID == ord.OrderID).FirstOrDefault();
        val.OrderID = ord.OrderID;
        val.EmployeeID = ord.EmployeeID;
        val.CustomerID = ord.CustomerID;
        val.Freight = ord.Freight;
        val.OrderDate = ord.OrderDate;
        val.ShipCity = ord.ShipCity;
    }
    else if (value.action == "insert")
    {
        OrdersDetails.GetAllRecords().Insert(0, value.value);
    }
    else if (value.action == "remove")
    {
        OrdersDetails.GetAllRecords().Remove(OrdersDetails.GetAllRecords().Where(or => or.OrderID == int.Parse(value.key.ToString())).FirstOrDefault());
        return Json(value);
    }
    return Json(value.value);
}

public class ICRUDModel<T> where T : class
{
    public string action { get; set; }

    public string table { get; set; }

    public string keyColumn { get; set; }

    public object key { get; set; }

    public T value { get; set; }

    public List<T> added { get; set; }

    public List<T> changed { get; set; }

    public List<T> deleted { get; set; }

    public IDictionary<string, object> @params { get; set; }
}

Please refer to the following screenshot to know about the action parameter.

crudupdate

If you specify InsertUrl along with CrudUrl, then while adding InsertUrl only will be invoked.

Batch URL

The BatchUrl property supports only for batch editing mode. You can specify the controller action mapping URL to perform batch operation on the server-side.

The following code example describes the above behavior.

razor
batch.cs
Copied to clipboard
@Html.EJS().Grid("grid").DataSource(dataManger =>
 {
      dataManger.Url("/Home/UrlDatasource").BatchUrl("/Home/BatchUpdate").Adaptor("UrlAdaptor");
 }).Columns(col =>
 {
    col.Field("OrderID").HeaderText("OrderID").IsPrimaryKey(true).Width("50").Add();
    col.Field("CustomerID").HeaderText("CustomerID").Width("90").Add();
    col.Field("EmployeeID").HeaderText("EmployeeID").Width("90").Add();
    col.Field("Freight").HeaderText("Freight").Width("90").Add();

}).AllowPaging().EditSettings(edit => { edit.AllowAdding(true).AllowEditing(true).AllowDeleting(true).Mode(Syncfusion.EJ2.Grids.EditMode.Batch); }).Toolbar(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" }).Render()
Copied to clipboard
public ActionResult UrlDatasource(DataManagerRequest dm)
{
    IEnumerable DataSource = OrdersDetails.GetAllRecords();
    DataOperations operation = new DataOperations();
    int count = DataSource.Cast<OrdersDetails>().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);
}

public ActionResult BatchUpdate(string action, CRUDModel batchmodel)
{
    if (batchmodel.Changed != null)
    {
        for (var i = 0; i < batchmodel.Changed.Count(); i++)
        {
            var ord = batchmodel.Changed[i];
            OrdersDetails val = orddata.Where(or => or.OrderID == ord.OrderID).FirstOrDefault();
            val.OrderID = ord.OrderID;
            val.EmployeeID = ord.EmployeeID;
            val.CustomerID = ord.CustomerID;
            val.Freight = ord.Freight;
            val.OrderDate = ord.OrderDate;
            val.ShipCity = ord.ShipCity;
            val.ShipAddress = ord.ShipAddress;
            val.ShippedDate = ord.ShippedDate;
        }
    }

    if (batchmodel.Deleted != null) 
    { 
        for (var i = 0; i < batchmodel.Deleted.Count(); i++)
        {
            orddata.Remove(orddata.Where(or => or.OrderID == batchmodel.Deleted[i].OrderID).FirstOrDefault());
        }
    }

    if (batchmodel.Added != null) 
    { 
        for (var i = 0; i < batchmodel.Added.Count(); i++)
        {
            orddata.Insert(0, batchmodel.Added[i]);
        }
    }
    var data = orddata.ToList();
    return Json(data, JsonRequestBehavior.AllowGet);
}

public class CRUDModel
{
    public List<OrdersDetails> Added { get; set; }

    public List<OrdersDetails> Changed { get; set; }

    public List<OrdersDetails> Deleted { get; set; }

    public OrdersDetails Value { get; set; }

    public int key { get; set; }

    public string action { get; set; }
}
Copied to clipboard
public ActionResult BatchUpdate([FromBody]string action, List<EditableOrder> added, List<EditableOrder> changed, List<EditableOrder> deleted, int? key)
{
//Save the batch changes in database
}

batch

Default column values on add new

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.

razor
defaultcolumnvalue.cs
Copied to clipboard
@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()
Copied to clipboard
public IActionResult Index()
 {
   var orders= OrderDetails.GetAllRecords();
   ViewBag.DataSource = orders;            
   return View();
 }

Custom validation

You can define your own custom validation rules for the specific columns by using Form Validator custom rules.

In the below demo, custom validation applied for CustomerID column.

razor
customvalidation.cs
Copied to clipboard
@Html.EJS().Grid("CustomValid").DataSource((IEnumerable<object>)ViewBag.DataSource).Columns(col =>
{
   col.Field("OrderID").HeaderText("Order ID").IsPrimaryKey(true).Width("120").TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).Add();
   col.Field("CustomerID").HeaderText("Customer Name").Width("150").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); }).Load("load").Toolbar(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" }).Render()

<script>

    function load(args) {
        this.columns[1].validationRules = { required: true, minLength: [customFn, 'Need atleast 5 letters'] };
    }

    function customFn(args) {
        return args['value'].length >= 5;
    };

</script>
Copied to clipboard
public IActionResult Index()
 {
   ViewBag.DataSource = OrdersDetails.GetAllRecords();            
   return View();
 }

Disable editing for particular column

You can disable editing for particular columns by using the AllowEditing property of Column.

In the following demo, editing is disabled for the CustomerID column.

razor
disableeditforcolumn.cs
Copied to clipboard
@Html.EJS().Grid("InlineEditing").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").AllowEditing(false).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).Mode(Syncfusion.EJ2.Grids.EditMode.Normal); }).Toolbar(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" }).Render()
Copied to clipboard
public IActionResult Index()
 {
   var orders = OrderDetails.GetAllRecords();
   ViewBag.datasource = orders;            
   return View();
 }

Troubleshoot: Editing works only for first row

The Editing functionalities can be performed based upon the primary key value of the selected row. If IsPrimaryKey is not defined in the grid, then edit or delete action take places the first row.

See also