Search results

Editing

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 e-grid-column tag helper as 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 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.

tagHelper
edit.cs
<ejs-grid id="Grid" dataSource="@ViewBag.DataSource" height="315" allowPaging="true">
    <e-grid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true"></e-grid-editSettings>
    <e-grid-columns>
        <e-grid-column field="OrderID"  headerText="Order ID" isPrimaryKey="true" textAlign="Right" width="100"></e-grid-column>                
        <e-grid-column field="CustomerID" headerText="Customer ID" type="string" width="120"></e-grid-column>                
        <e-grid-column field="Freight" headerText="Freight" textAlign="Right" format="C2" editType="numericedit" width="120"></e-grid-column>                               
        <e-grid-column field="ShipCountry" headerText="Ship Country" width="150"></e-grid-column>                
    </e-grid-columns>
</ejs-grid>
public IActionResult Index()
{
    var Order = OrderDetails.GetAllRecords();
    ViewBag.DataSource = Order;
    return View();
}
  • If isIdentity property of e-grid-column 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 property of e-grid-column 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.

tagHelper
edittoolbar.cs
<ejs-grid id="Grid" dataSource="@ViewBag.DataSource" height="273" toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Cancel", "Update" })">
    <e-grid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true"></e-grid-editSettings>
        <e-grid-columns>
            <e-grid-column field="OrderID"  headerText="Order ID" isPrimaryKey="true" textAlign="Right" width="100"></e-grid-column>                
            <e-grid-column field="CustomerID" headerText="Customer ID" type="string" width="120"></e-grid-column>                
            <e-grid-column field="Freight" headerText="Freight" textAlign="Right" format="C2" editType="numericedit" width="120"></e-grid-column>                               
            <e-grid-column field="ShipCountry" headerText="Ship Country" width="150"></e-grid-column>                
        </e-grid-columns>
</ejs-grid>
public IActionResult Index()
{
    var Order = OrderDetails.GetAllRecords();
    ViewBag.DataSource = Order;
    return View();
}

Cell edit type and its params

The editType property of e-grid-column tag helper 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 edit property of e-grid-column tag helper .

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() }
tagHelper
celleditparams.cs
@{
    var editParams = new { @params = new { value = "Germany" } };
 }

<ejs-grid id="Grid" dataSource="@ViewBag.DataSource" toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Cancel", "Update" })">
    <e-grid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true"></e-grid-editSettings>
    <e-grid-columns>
        <e-grid-column field="OrderID" headerText="Order ID" isPrimaryKey="true" textAlign="Right" width="100"></e-grid-column>
        <e-grid-column field="CustomerID" headerText="Customer ID" type="string" width="120"></e-grid-column>
        <e-grid-column field="Freight" headerText="Freight" textAlign="Right" format="C2" editType="numericedit" width="120"></e-grid-column>
        <e-grid-column field="ShipCountry" headerText="Ship Country" width="150" edit=editParams editType="dropdownedit">
        </e-grid-column>
    </e-grid-columns>
</ejs-grid>
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.

tagHelper
celledittemplate.cs
<ejs-grid id="Grid" dataSource="@ViewBag.datasource" height="315" allowPaging="true">
    <e-grid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true"></e-grid-editSettings>
    <e-grid-columns>
        <e-grid-column field="OrderID" headerText="Order ID" isPrimaryKey="true" textAlign="Right" width="100"></e-grid-column>
        <e-grid-column field="CustomerID" headerText="Customer ID" type="string" width="120"></e-grid-column>
        <e-grid-column field="OrderDate" headerText="Order Date" format="yMd" edit="@(new {create = "create", read = "read", destroy = "destroy", write = "write"})" width="120"></e-grid-column>
        <e-grid-column field="Freight" headerText="Freight" textAlign="Right" format="C2" editType="numericedit" width="120"></e-grid-column>
        <e-grid-column field="ShipCountry" headerText="Ship Country" width="150"></e-grid-column>
    </e-grid-columns>
</ejs-grid>


<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>
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 mode property of e-grid-editSettings tag helper as Normal.

tagHelper
inline.cs
<ejs-grid id="Grid" dataSource="@ViewBag.DataSource" height="273" toolbar="@(new List<string>() { "Add", "Edit", "Delete","Update","Cancel" })">
    <e-grid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true" mode="Normal"></e-grid-editSettings>
        <e-grid-columns>
            <e-grid-column field="OrderID" headerText="Order ID" validationRules="@(new { required=true})" isPrimaryKey="true" textAlign="Right" width="100"></e-grid-column>
            <e-grid-column field="CustomerID" headerText="Customer ID" validationRules="@(new { required=true, minLength=3})" type="string" width="120"></e-grid-column>
            <e-grid-column field="Freight" headerText="Freight" textAlign="Right" format="C2" editType="numericedit" width="120"></e-grid-column>
            <e-grid-column field="ShipCountry" headerText="Ship Country" width="150"></e-grid-column>
        </e-grid-columns>
</ejs-grid>
public IActionResult Index()
{
    var Order = OrderDetails.GetAllRecords();
    ViewBag.DataSource = Order;
    return View();
}

Normal edit mode is default mode of editing.

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 property of e-grid-editSettings tag helper as Dialog.

tagHelper
dialog.cs
<ejs-grid id="Grid" dataSource="@ViewBag.DataSource" height="273" toolbar="@(new List<string>() { "Add", "Edit", "Delete","Update","Cancel" })">
    <e-grid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true" mode="Dialog"></e-grid-editSettings>
        <e-grid-columns>
            <e-grid-column field="OrderID" headerText="Order ID" validationRules="@(new { required=true})" isPrimaryKey="true" textAlign="Right" width="100"></e-grid-column>
            <e-grid-column field="CustomerID" headerText="Customer ID" validationRules="@(new { required=true, minLength=3})" type="string" width="120"></e-grid-column>
            <e-grid-column field="Freight" headerText="Freight" textAlign="Right" format="C2" editType="numericedit" width="120"></e-grid-column>
            <e-grid-column field="ShipCountry" headerText="Ship Country" width="150"></e-grid-column>
        </e-grid-columns>
</ejs-grid>
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 property of e-grid-editSettings tag helper as Batch.

tagHelper
batch.cs
<ejs-grid id="Grid" dataSource="@ViewBag.DataSource" height="273" toolbar="@(new List<string>() { "Add", "Delete","Update","Cancel" })">
  <e-grid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true" mode="Batch"></e-grid-editSettings>
  <e-grid-columns>
    <e-grid-column field="OrderID" headerText="Order ID" validationRules="@(new { required=true})" isPrimaryKey="true" textAlign="Right" width="100"></e-grid-column>
    <e-grid-column field="CustomerID" headerText="Customer ID" validationRules="@(new { required=true, minLength=3})" type="string" width="120"></e-grid-column>
    <e-grid-column field="Freight" headerText="Freight" textAlign="Right" format="C2" editType="numericedit" width="120"></e-grid-column>
    <e-grid-column field="ShipCountry" headerText="Ship Country" width="150"></e-grid-column>
  </e-grid-columns>
</ejs-grid>
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 property of e-grid-editSettings tag helper as Dialog/Inline and template property 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.

tagHelper
addpatial.cs
addpatialMVC.cs
dialog.cs
dialogtemplatemodel.cs
editpartial.cs
editpartialMVC.cs
@{
    ViewData["Title"] = "DialogTemplate";
}

<div class="control-section">
    <ejs-grid id="Grid" dataSource="@ViewBag.DataSource" actionComplete="actionComplete" toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" })" allowPaging="true">
        <e-grid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true" mode="Dialog" template='#dialogtemplate'></e-grid-editSettings>
        <e-grid-pagesettings pageCount="5 "></e-grid-pagesettings>
        <e-grid-columns>
           <e-grid-column field="OrderID" headerText="Order ID" isPrimaryKey="true" validationRules="@(new { required=true})" textAlign="Right" width="120"></e-grid-column>
           <e-grid-column field="CustomerID" headerText="Customer Name" validationRules="@(new { required=true})" width="150"></e-grid-column>
           <e-grid-column field="ShipCountry" headerText="Ship Country" editType="dropdownedit" width="150"></e-grid-column>
        </e-grid-columns>
    </ejs-grid>
 </div>

<script id='dialogtemplate' type="text/x-template">
    <div id="dialogTemp"></div>
</script>

    
<script>
    function actionComplete(args) {
        if (args.requestType === 'beginEdit') {
            var ajax = new ej.base.Ajax({
                url: "/Grid/EditPartial", //render the partial view
                type: "POST",
                contentType: "application/json",
                data: JSON.stringify({ value: args.rowData })
            });
            ajax.send().then(function (data) {
                appendElement(data, args.form); //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: "/Grid/AddPartial", //render the partial view
                type: "POST",
                contentType: "application/json",
                data: JSON.stringify({ value: args.rowData })
            });
            ajax.send().then(function (data) {
                appendElement(data, args.form); //Render the edit form with selected record
                args.form.elements.namedItem('OrderID').focus();
            }).catch(function (xhr) {
                console.log(xhr);
            });
        }
    }

    function appendElement(elementString, form) {
        form.querySelector("#dialogTemp").innerHTML = elementString;
        var script = document.createElement('script');
        script.type = "text/javascript";
        var serverScript = form.querySelector("#dialogTemp").querySelector('script');
        script.textContent = serverScript.innerHTML;
        document.head.appendChild(script);
        serverScript.remove();
    }
</script>
@model TestApplication.Models.OrdersDetails
@*//define the model for store the model values*@

@using Syncfusion.EJ2

<div>
    <div class="form-row">
        <div class="form-group col-md-6">
            <div class="e-float-input e-control-wrapper">
                <input asp-for="OrderID" name="OrderID" type='text' />
                <span class="e-float-line"></span>
                <label asp-for="OrderID" class="e-float-text e-label-top">Order ID</label>
            </div>
        </div>
        <div class="form-group col-md-6">
            <div class="e-float-input e-control-wrapper">
                <input asp-for="CustomerID" name="CustomerID" />
                <span class="e-float-line"></span>
                <label asp-for="CustomerID" class="e-float-text e-label-top">Customer Name</label>
            </div>
        </div>
    </div>

    <div class="form-row">
        <div class="form-group col-md-6">
            <ejs-numerictextbox id="Freight" format="C2" placeholder="Freight" floatLabelType="Always"></ejs-numerictextbox>
        </div>
        <div class="form-group col-md-6">
            <ejs-datepicker id="OrderDate" placeholder="Order Date" floatLabelType="Always"></ejs-datepicker>
        </div>
    </div>

    <div class="form-row">
        <div class="form-group col-md-6">
            <ejs-dropdownlist id="ShipCountry" dataSource="@ViewBag.datasource" placeholder="Ship Country" floatLabelType="Always" popupHeight="300px">
                <e-dropdownlist-fields text="ShipCountry" value="ShipCountry"></e-dropdownlist-fields>
            </ejs-dropdownlist>

        </div>
        <div class="form-group col-md-6">
            <ejs-dropdownlist id="ShipCity" dataSource="@ViewBag.datasource" placeholder="Ship City" floatLabelType="Always" popupHeight="300px">
                <e-dropdownlist-fields text="ShipCity" value="ShipCity"></e-dropdownlist-fields>
            </ejs-dropdownlist>
        </div>
    </div>
    <div class="form-row">
        <div class="form-group col-md-12">
            <div class="e-float-input e-control-wrapper">
                <textarea asp-for="ShipAddress"></textarea>
                <span class="e-float-line"></span>
                <label asp-for="ShipAddress" class="e-float-text e-label-top">Ship Address</label>
            </div>
        </div>
    </div>
</div>

<ejs-scripts></ejs-scripts>
@model MVCApplication.Models.OrdersDetails
@*//define the model for store the model values*@

@using Syncfusion.EJ2
@using Syncfusion.EJ2.DropDowns

<div>
    <div class="form-row">
        <div class="form-group col-md-6">
            <div class="e-float-input e-control-wrapper">
                <input asp-for="OrderID" name="OrderID" type='text' />
                <span class="e-float-line"></span>
                <label asp-for="OrderID" class="e-float-text e-label-top">Order ID</label>
            </div>
        </div>
        <div class="form-group col-md-6">
            <div class="e-float-input e-control-wrapper">
                <input asp-for="CustomerID" name="CustomerID" />
                <span class="e-float-line"></span>
                <label asp-for="CustomerID" class="e-float-text e-label-top">Customer Name</label>
            </div>
        </div>
    </div>

    <div class="form-row">
        <div class="form-group col-md-6">
            @Html.EJS().NumericTextBox("Freight").Format("C2").Placeholder("Freight").Render()
        </div>
        <div class="form-group col-md-6">
            @Html.EJS().DatePicker("OrderDate").Placeholder("Order Date").Render()
        </div>
    </div>

    <div class="form-row">
        <div class="form-group col-md-6">
            @Html.EJS().DropDownList("ShipCountry").DataSource(ViewBag.dataSource).Placeholder("Ship Country").Fields(new DropDownListFieldSettings { Text = "ShipCountry", Value = "ShipCountry" }).Render()

        </div>
        <div class="form-group col-md-6">
            @Html.EJS().DropDownList("ShipCity").DataSource(ViewBag.dataSource).Placeholder("Ship City").Fields(new DropDownListFieldSettings { Text = "ShipCity", Value = "ShipCity" }).Render()
        </div>
    </div>
    <div class="form-row">
        <div class="form-group col-md-12">
            <div class="e-float-input e-control-wrapper">
                <textarea asp-for="ShipAddress"></textarea>
                <span class="e-float-line"></span>
                <label asp-for="ShipAddress" class="e-float-text e-label-top">Ship Address</label>
            </div>
        </div>
    </div>
</div>

@Html.EJS().ScriptManager()
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");
}
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace EJ2MVCSampleBrowser.Models
{
    public class DialogTemplateModel
    {
        [Required]
        public int? OrderID { get; set; }
        [Required, MinLength(3)]
        public string CustomerID { get; set; }
        public int? EmployeeID { get; set; }
        public double Freight { get; set; }
        public string ShipCity { get; set; }
        public bool Verified { get; set; }
        public DateTime OrderDate { get; set; }

        public string ShipName { get; set; }

        public string ShipCountry { get; set; }

        public DateTime ShippedDate { get; set; }
        public string ShipAddress { get; set; }
    }
}
@model TestApplication.Models.OrdersDetails
@*//define the model for store the model values*@

@using Syncfusion.EJ2

<div>
    <div class="form-row">
        <div class="form-group col-md-6">
            <div class="e-float-input e-control-wrapper">
                <input asp-for="OrderID" name="OrderID" value=@Model.OrderID.ToString() disabled type='text' />
                <span class="e-float-line"></span>
                <label asp-for="OrderID" class="e-float-text e-label-top">Order ID</label>
            </div>
        </div>
        <div class="form-group col-md-6">
            <div class="e-float-input e-control-wrapper">
                <input asp-for="CustomerID" name="CustomerID" value=@Model.CustomerID />
                <span class="e-float-line"></span>
                <label asp-for="CustomerID" class="e-float-text e-label-top">Customer Name</label>
            </div>
        </div>
    </div>

    <div class="form-row">
        <div class="form-group col-md-6">
            <ejs-numerictextbox id="Freight" value=@Model.Freight format="C2" placeholder="Freight" floatLabelType="Always"></ejs-numerictextbox>
        </div>
        <div class="form-group col-md-6">
            <ejs-datepicker id="OrderDate" value=@Model.OrderDate placeholder="Order Date" floatLabelType="Always"></ejs-datepicker>
        </div>
    </div>

    <div class="form-row">
        <div class="form-group col-md-6">
            <ejs-dropdownlist id="ShipCountry" value=@Model.ShipCountry dataSource="@ViewBag.datasource" placeholder="Ship Country" floatLabelType="Always" popupHeight="300px">
                <e-dropdownlist-fields text="ShipCountry" value="ShipCountry"></e-dropdownlist-fields>
            </ejs-dropdownlist>

        </div>
        <div class="form-group col-md-6">
            <ejs-dropdownlist id="ShipCity" value=@Model.ShipCity dataSource="@ViewBag.datasource" placeholder="Ship City" floatLabelType="Always" popupHeight="300px">
                <e-dropdownlist-fields text="ShipCity" value="ShipCity"></e-dropdownlist-fields>
            </ejs-dropdownlist>
        </div>
    </div>
    <div class="form-row">
        <div class="form-group col-md-12">
            <div class="e-float-input e-control-wrapper">
                <textarea asp-for="ShipAddress">@Model.ShipAddress</textarea>
                <span class="e-float-line"></span>
                <label asp-for="ShipAddress" class="e-float-text e-label-top">Ship Address</label>
            </div>
        </div>
    </div>
</div>

<ejs-scripts></ejs-scripts>
@model MVCApplication.Models.OrdersDetails
@*//define the model for store the model values*@

@using Syncfusion.EJ2
@using Syncfusion.EJ2.DropDowns

<div>
    <div class="form-row">
        <div class="form-group col-md-6">
            <div class="e-float-input e-control-wrapper">
                <input asp-for="OrderID" name="OrderID" value=@Model.OrderID.ToString() disabled type='text' />
                <span class="e-float-line"></span>
                <label asp-for="OrderID" class="e-float-text e-label-top">Order ID</label>
            </div>
        </div>
        <div class="form-group col-md-6">
            <div class="e-float-input e-control-wrapper">
                <input asp-for="CustomerID" name="CustomerID" value=@Model.CustomerID />
                <span class="e-float-line"></span>
                <label asp-for="CustomerID" class="e-float-text e-label-top">Customer Name</label>
            </div>
        </div>
    </div>

    <div class="form-row">
        <div class="form-group col-md-6">
            @Html.EJS().NumericTextBox("Freight").Value(Model.Freight).Format("C2").Placeholder("Freight").Render()
        </div>
        <div class="form-group col-md-6">
            @Html.EJS().DatePicker("OrderDate").Value(Model.OrderDate).Placeholder("Order Date").Render()
        </div>
    </div>

    <div class="form-row">
        <div class="form-group col-md-6">
            @Html.EJS().DropDownList("ShipCountry").DataSource(ViewBag.dataSource).Value(Model.ShipCountry).Placeholder("Ship Country").Fields(new DropDownListFieldSettings { Text = "ShipCountry", Value = "ShipCountry" }).Render()
        </div>
        <div class="form-group col-md-6">
            @Html.EJS().DropDownList("ShipCity").DataSource(ViewBag.dataSource).Value(Model.ShipCity).Placeholder("Ship City").Fields(new DropDownListFieldSettings { Text = "ShipCity", Value = "ShipCity" }).Render()
        </div>
    </div>
    <div class="form-row">
        <div class="form-group col-md-12">
            <div class="e-float-input e-control-wrapper">
                <textarea asp-for="ShipAddress">@Model.ShipAddress</textarea>
                <span class="e-float-line"></span>
                <label asp-for="ShipAddress" class="e-float-text e-label-top">Ship Address</label>
            </div>
        </div>
    </div>
</div>

@Html.EJS().ScriptManager()

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 actionBegin event at the time of requestType as save.

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

    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.

    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.

    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 property of [e-grid-editSettings] tag helper as Bottom.

tagHelper
rowposition.cs
<ejs-grid id="Grid" dataSource="@ViewBag.DataSource" height="273" toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Cancel", "Update" })">
    <e-grid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true" newRowPosition="Bottom"></e-grid-editSettings>
    <e-grid-columns>
        <e-grid-column field="OrderID" headerText="Order ID" isPrimaryKey="true" textAlign="Right" width="100"></e-grid-column>
        <e-grid-column field="CustomerID" headerText="Customer ID" type="string" width="120"></e-grid-column>
        <e-grid-column field="Freight" headerText="Freight" textAlign="Right" format="C2" editType="numericedit" width="120"></e-grid-column>
        <e-grid-column field="ShipCountry" headerText="Ship Country" width="150"></e-grid-column>
    </e-grid-columns>
</ejs-grid>
public IActionResult Index()
{
    var Order = OrderDetails.GetAllRecords();
    ViewBag.DataSource = Order;
    return View();
}

Add newRowPostion is supported for Normal and Batch editing modes.

Default column values on add new record

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 property of e-grid-column tag helper.

tagHelper
defaultcolumnvalue.cs
<ejs-grid id="Grid" dataSource="@ViewBag.DataSource" height="273" toolbar="@(new List<string>() { "Add", "Edit", "Delete","Update", "Cancel"})">
    <e-grid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true" mode="Normal"></e-grid-editSettings>
    <e-grid-columns>
        <e-grid-column field="OrderID"  headerText="Order ID" isPrimaryKey="true" textAlign="Right" width="100"></e-grid-column>                
        <e-grid-column field="CustomerID" headerText="Customer ID"  defaultValue="HANAR" type="string" width="120"></e-grid-column>                
        <e-grid-column field="Freight" headerText="Freight" textAlign="Right" format="C2" editType="numericedit" width="120"></e-grid-column>
        <e-grid-column field="ShipCountry" headerText="Ship Country" width="150"></e-grid-column>                
    </e-grid-columns>
</ejs-grid>
public IActionResult Index()
 {
   var orders= OrderDetails.GetAllRecords();
   ViewBag.DataSource = orders;            
   return View();
 }

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 e-grid-column tag helper.

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.
tagHelper
commandcolumn.cs
@{
    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" } });
  }

<ejs-grid id="Grid" dataSource="@ViewBag.DataSource" height="310">
    <e-grid-editSettings allowDeleting="true" allowEditing="true" mode="Normal"></e-grid-editSettings>
    <e-grid-columns>
        <e-grid-column field="OrderID"  headerText="Order ID" isPrimaryKey="true" textAlign="Right" width="100"></e-grid-column>                
        <e-grid-column field="CustomerID" headerText="Customer ID" type="string" width="120"></e-grid-column>                
        <e-grid-column field="Freight" headerText="Freight" textAlign="Right" format="C2" editType="numericedit" width="120"></e-grid-column>
        <e-grid-column field="ShipCountry" headerText="Ship Country" width="150"></e-grid-column>   
        <e-grid-column headerText="Manage Records" width="120" command=commands>
        </e-grid-column>
    </e-grid-columns>
</ejs-grid>
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 e-grid-column tag helper and the action for the custom buttons can be defined using commandClick event.

tagHelper
customcommand.cs
@{
    List<object> commands = new List<object>();
    commands.Add(new { type = "userstatus", buttonOption = new { content = "Details", cssClass = "e-flat e-details" } }); // custom
}

<div class="control-section">
    <ejs-grid id="Grid" dataSource="@ViewBag.DataSource"  commandClick="commandClick" allowPaging="true">
        <e-grid-editSettings allowAdding="false" allowDeleting="false" allowEditing="true"></e-grid-editSettings>
        <e-grid-columns>
            <e-grid-column field="OrderID" headerText="Order ID" validationRules="@(new { required=true})" isPrimaryKey="true" textAlign="Right" width="100"></e-grid-column>
            <e-grid-column field="Verified" headerText="Verified" editType="booleanedit" displayAsCheckBox="true" textAlign="Center" type="boolean" width="100"></e-grid-column>
            <e-grid-column headerText="Manage Records" width="150" commands="commands"></e-grid-column>
        </e-grid-columns>
    </ejs-grid>
</div>

<script>
        function commandClick(args) {
            alert(JSON.stringify(args.rowData));  // display row data
        }
</script>
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 property of e-grid-editSettings as true.

tagHelper
deleteconfirm.cs
<ejs-grid id="Grid" dataSource="@ViewBag.DataSource" height="273" toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Update","Cancel"  })">
    <e-grid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true" mode="Normal" showDeleteConfirmDialog="true"></e-grid-editSettings>
    <e-grid-columns>
        <e-grid-column field="OrderID"  headerText="Order ID" isPrimaryKey="true" textAlign="Right" width="100"></e-grid-column>                
        <e-grid-column field="CustomerID" headerText="Customer ID" type="string" width="120"></e-grid-column>                
        <e-grid-column field="Freight" headerText="Freight" textAlign="Right" format="C2" editType="numericedit" width="120"></e-grid-column>          
        <e-grid-column field="ShipCountry" headerText="Ship Country" width="150"></e-grid-column>                
    </e-grid-columns>            
</ejs-grid>
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.

tagHelper
batchconfirm.cs
<ejs-grid id="Grid" dataSource="@ViewBag.DataSource" height="273" toolbar="@(new List<string>() { "Add", "Delete","Update", "Cancel"  })">
    <e-grid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true" mode="Batch" showDeleteConfirmDialog="true"></e-grid-editSettings>
    <e-grid-columns>
        <e-grid-column field="OrderID" headerText="Order ID" isPrimaryKey="true" textAlign="Right" width="100"></e-grid-column>
        <e-grid-column field="CustomerID" headerText="Customer ID" type="string" width="120"></e-grid-column>
        <e-grid-column field="Freight" headerText="Freight" textAlign="Right" format="C2" editType="numericedit" width="120"></e-grid-column>
        <e-grid-column field="ShipCountry" headerText="Ship Country" width="150"></e-grid-column>
    </e-grid-columns>
</ejs-grid>
public IActionResult Index()
{
    var Order = OrderDetails.GetAllRecords();
    ViewBag.DataSource = Order;
    return View();
}

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 in validationRules property of e-grid-column tag helper.

tagHelper
columnvalid.cs
<ejs-grid id="Grid" dataSource="@ViewBag.DataSource" height="273" toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Cancel", "Update" })">
    <e-grid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true" mode="Normal" showConfirmDialog="true" showDeleteConfirmDialog="true"></e-grid-editSettings>
    <e-grid-columns>
        <e-grid-column field="OrderID"  headerText="Order ID" isPrimaryKey="true" textAlign="Right" width="100"  validationRules="@(new { required= true })"></e-grid-column>                
        <e-grid-column field="CustomerID" headerText="Customer ID" type="string" width="120" validationRules="@(new { required= true, minLength= 3 })"></e-grid-column>
        <e-grid-column field="Freight" headerText="Freight" textAlign="Right" format="C2" editType="numericedit" width="120"></e-grid-column>                               
        <e-grid-column field="ShipCountry" headerText="Ship Country" width="150"></e-grid-column>                
    </e-grid-columns>
 </ejs-grid>
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.

tagHelper
customvalidation.cs
<ejs-grid id="Grid" dataSource="@ViewBag.DataSource" height="273" toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Cancel", "Update" })" load="load">
    <e-grid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true" mode="Normal"></e-grid-editSettings>
    <e-grid-columns>
        <e-grid-column field="OrderID" headerText="Order ID" isPrimaryKey="true" textAlign="Right" width="100" validationRules="@(new{ required = true })"></e-grid-column>
        <e-grid-column field="CustomerID" headerText="Customer ID" type="string" width="120"></e-grid-column>
        <e-grid-column field="Freight" headerText="Freight" textAlign="Right" format="C2" editType="numericedit" width="120"></e-grid-column>
        <e-grid-column field="ShipCountry" headerText="Ship Country" width="150"></e-grid-column>
    </e-grid-columns>
</ejs-grid>

<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>
public IActionResult Index()
 {
   ViewBag.DataSource = OrdersDetails.GetAllRecords();            
   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.

tagHelper
urladaptor.cs
<ejs-grid id="Grid" height="273" toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Cancel", "Update" })" allowPaging="true">
    <e-data-manager url="/Home/UrlDataSource" insertUrl="/Home/Insert" updateUrl="/Home/Update" removeUrl="/Home/Delete" adaptor="UrlAdaptor"></e-data-manager>
    <e-grid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true" mode="Normal"></e-grid-editSettings>
    <e-grid-columns>
        <e-grid-column field="OrderID" headerText="Order ID" isPrimaryKey="true" textAlign="Right" width="100"></e-grid-column>
        <e-grid-column field="CustomerID" headerText="Customer ID" type="string" width="120"></e-grid-column>
        <e-grid-column field="Freight" headerText="Freight" textAlign="Right" format="C2" editType="numericedit" width="120"></e-grid-column>
        <e-grid-column field="ShipCountry" headerText="Ship Country" width="150"></e-grid-column>
    </e-grid-columns>
</ejs-grid>
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);
}

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.

tagHelper
data.cs
<ejs-grid id="Grid" height="273" toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Cancel", "Update" })" allowPaging="true">
    <e-data-manager url="/Home/UrlDataSource" insertUrl="/Home/Insert" updateUrl="/Home/Update" removeUrl="/Home/Delete" adaptor="UrlAdaptor"></e-data-manager>
    <e-grid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true" mode="Normal"></e-grid-editSettings>
    <e-grid-columns>
        <e-grid-column field="OrderID" headerText="Order ID" isPrimaryKey="true" textAlign="Right" width="100"></e-grid-column>
        <e-grid-column field="CustomerID" headerText="Customer ID" type="string" width="120"></e-grid-column>
        <e-grid-column field="Freight" headerText="Freight" textAlign="Right" format="C2" editType="numericedit" width="120"></e-grid-column>
        <e-grid-column field="ShipCountry" headerText="Ship Country" width="150"></e-grid-column>
    </e-grid-columns>
</ejs-grid>
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);
}

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.

tagHelper
insert.cs
<ejs-grid id="Grid" height="273" toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Cancel", "Update" })" allowPaging="true">
    <e-data-manager url="/Home/UrlDataSource" insertUrl="/Home/Insert" updateUrl="/Home/Update" removeUrl="/Home/Delete" adaptor="UrlAdaptor"></e-data-manager>
    <e-grid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true" mode="Normal"></e-grid-editSettings>
    <e-grid-columns>
        <e-grid-column field="OrderID" headerText="Order ID" isPrimaryKey="true" textAlign="Right" width="100"></e-grid-column>
        <e-grid-column field="CustomerID" headerText="Customer ID" type="string" width="120"></e-grid-column>
        <e-grid-column field="Freight" headerText="Freight" textAlign="Right" format="C2" editType="numericedit" width="120"></e-grid-column>
        <e-grid-column field="ShipCountry" headerText="Ship Country" width="150"></e-grid-column>
    </e-grid-columns>
</ejs-grid>
public ActionResult Insert([FromBody]ICRUDModel<OrdersDetails> value)
{
    OrdersDetails.GetAllRecords().Insert(0, value.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; }
}

If you get posted data as null at the server side, then it might be due to the model state failure. You can check this using ModelState.IsValid and get the failure error details using ModelState.Values property.

The newly added record details are bound to the value 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.

tagHelper
update.cs
<ejs-grid id="Grid" height="273" toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Cancel", "Update" })" allowPaging="true">
    <e-data-manager url="/Home/UrlDataSource" insertUrl="/Home/Insert" updateUrl="/Home/Update" removeUrl="/Home/Delete" adaptor="UrlAdaptor"></e-data-manager>
    <e-grid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true" mode="Normal"></e-grid-editSettings>
    <e-grid-columns>
        <e-grid-column field="OrderID" headerText="Order ID" isPrimaryKey="true" textAlign="Right" width="100"></e-grid-column>
        <e-grid-column field="CustomerID" headerText="Customer ID" type="string" width="120"></e-grid-column>
        <e-grid-column field="Freight" headerText="Freight" textAlign="Right" format="C2" editType="numericedit" width="120"></e-grid-column>
        <e-grid-column field="ShipCountry" headerText="Ship Country" width="150"></e-grid-column>
    </e-grid-columns>
</ejs-grid>
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; }
}

If you get posted data as null at the server side, then it might be due to the model state failure. You can check this using ModelState.IsValid and get the failure error details using ModelState.Values property.

The updated record details are bound to the value 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.

tagHelper
delete.cs
<ejs-grid id="Grid" height="273" toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Cancel", "Update" })" allowPaging="true">
    <e-data-manager url="/Home/UrlDataSource" insertUrl="/Home/Insert" updateUrl="/Home/Update" removeUrl="/Home/Delete" adaptor="UrlAdaptor"></e-data-manager>
    <e-grid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true" mode="Normal"></e-grid-editSettings>
    <e-grid-columns>
        <e-grid-column field="OrderID" headerText="Order ID" isPrimaryKey="true" textAlign="Right" width="100"></e-grid-column>
        <e-grid-column field="CustomerID" headerText="Customer ID" type="string" width="120"></e-grid-column>
        <e-grid-column field="Freight" headerText="Freight" textAlign="Right" format="C2" editType="numericedit" width="120"></e-grid-column>
        <e-grid-column field="ShipCountry" headerText="Ship Country" width="150"></e-grid-column>
    </e-grid-columns>
</ejs-grid>
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; }
}

If you get posted data as null at the server side, then it might be due to the model state failure. You can check this using ModelState.IsValid and get the failure error details using ModelState.Values property.

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.

tagHelper
crudurl.cs
<ejs-grid id="Grid" height="273" toolbar="@(new List<string>() { "Add", "Edit", "Delete","Update", "Cancel"})">
    <e-datamanager url="/Home/UrlDatasource" crudUrl="/Home/CrudUpdate" adaptor="UrlAdaptor"></e-datamanager>
    <e-grid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true" mode="Normal" showConfirmDialog="true" showDeleteConfirmDialog="true"></e-grid-editSettings>
    <e-grid-columns>
        <e-grid-column field="OrderID"  headerText="Order ID" isPrimaryKey="true" textAlign="Right" width="100"></e-grid-column>                
        <e-grid-column field="CustomerID" headerText="Customer ID" type="string" width="120"></e-grid-column>                
        <e-grid-column field="Freight" headerText="Freight" textAlign="Right" format="C2" editType="numericedit" width="120"></e-grid-column>                               
        <e-grid-column field="ShipCountry" headerText="Ship Country" width="150"></e-grid-column>                
    </e-grid-columns>
</ejs-grid>
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. If you get posted data as null at the server side, then it might be due to the model state failure. You can check this using ModelState.IsValid and get the failure error details using ModelState.Values property.

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.

tagHelper
batchurl.cs
<ejs-grid id="Grid" dataSource="ViewBag.DataSource" height="273" toolbar="@(new List<string>() { "Add", "Edit", "Delete","Update", "Cancel"})">
    <e-data-manager url="/Home/UrlDataSource" batchUrl="/Home/BatchUpdate" adaptor="UrlAdaptor"></e-data-manager>
    <e-grid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true" mode="Batch" showConfirmDialog="true" showDeleteConfirmDialog="true"></e-grid-editSettings>
    <e-grid-columns>
        <e-grid-column field="OrderID" headerText="Order ID" isPrimaryKey="true" textAlign="Right" width="100"></e-grid-column>
        <e-grid-column field="CustomerID" headerText="Customer ID" type="string" width="120"></e-grid-column>
        <e-grid-column field="Freight" headerText="Freight" textAlign="Right" format="C2" editType="numericedit" width="120"></e-grid-column>
        <e-grid-column field="ShipCountry" headerText="Ship Country" width="150"></e-grid-column>
    </e-grid-columns>
</ejs-grid>
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 IActionResult BatchUpdate([FromBody]CRUDModel batchmodel)
{
    if (batchmodel.Changed != null)
    {
        for (var i = 0; i < batchmodel.Changed.Count(); i++)
        {
            var ord = batchmodel.Changed[i];
            Orders val = order.Where(or => or.OrderID == ord.OrderID).FirstOrDefault();
            val.OrderID = ord.OrderID;
            val.EmployeeID = ord.EmployeeID;
            val.CustomerID = ord.CustomerID;
            val.ShipCity = ord.ShipCity;
        }
    }
    if (batchmodel.Deleted != null)
    {
        for (var i = 0; i < batchmodel.Deleted.Count(); i++)
        {
            order.Remove(order.Where(or => or.OrderID == batchmodel.Deleted[i].OrderID).FirstOrDefault());
        }
    }
    if (batchmodel.Added != null)
    {
        for (var i = 0; i < batchmodel.Added.Count(); i++)
        {
            order.Insert(0, batchmodel.Added[i]);
        }
    }
    var data = order.ToList();
    return Json(data);
}

If you get posted data as null at the server side, then it might be due to the model state failure. You can check this using ModelState.IsValid and get the failure error details using ModelState.Values property.

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

batch

Disable editing for particular column

You can disable editing for particular columns by using the allowEditing property of e-grid-column tag helper.

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

tagHelper
disableeditforcolumn.cs
<ejs-grid id="Grid" dataSource="@ViewBag.DataSource" height="273" toolbar="@(new List<string>() { "Add", "Edit", "Delete","Update", "Cancel" })">
    <e-grid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true" mode="Normal"></e-grid-editSettings>
    <e-grid-columns>
        <e-grid-column field="OrderID"  headerText="Order ID" isPrimaryKey="true" textAlign="Right" width="100"></e-grid-column>                
        <e-grid-column field="CustomerID" headerText="Customer ID" allowEditing="false"  type="string" width="120"></e-grid-column>                
        <e-grid-column field="Freight" headerText="Freight" textAlign="Right" format="C2" editType="numericedit" width="120"></e-grid-column>                               
        <e-grid-column field="ShipCountry" headerText="Ship Country" width="150"></e-grid-column>                
    </e-grid-columns>
</ejs-grid>
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 primaryKey is not defined in the grid, then edit or delete action take places the first row.

See also