Template Editing in ASP.NET MVC Tree Grid Component

21 Dec 202218 minutes to read

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.

@using Syncfusion.EJ2.Grids

@(Html.EJS().TreeGrid("TreeGrid").DataSource((IEnumerable<object>)ViewBag.datasource)
      .EditSettings(edit =>
      {
          edit.AllowAdding(true);
          edit.AllowDeleting(true);
          edit.AllowEditing(true);
          edit.Mode(Syncfusion.EJ2.TreeGrid.EditMode.Cell);
      })
       .Toolbar(new List<string>() { "Add", "Delete", "Update", "Cancel" })
       .Columns(col =>
       {
           col.Field("TaskId").HeaderText("Task ID").IsPrimaryKey(true).Width(120)
              .TextAlign(TextAlign.Right).Add();
           col.Field("TaskName").HeaderText("Task Name")
              .Edit(new
              {
                  create = "create",
                  read = "read",
                  write = "write",
                  destroy = "destroy"

              }).Width(230).ValidationRules(new { required = true }).Add();
           col.Field("StartDate").HeaderText("Start Date").Width(150).Format("yMd")
              .EditType("datepickeredit").TextAlign(TextAlign.Right).Add();
           col.Field("Duration").HeaderText("Duration").Width("110").EditType("numericedit")
              .Edit(new { @params = new { format = "n" } }).TextAlign(TextAlign.Right).Add();

       }).Height(400).ChildMapping("Children").TreeColumnIndex(1).Render())

<script>
    var autoCompleteObj, elem;
    function create(args) {
        elem = document.createElement('input');
        return elem;
    }
    function read(args) {
        return autoCompleteObj.value;
    }
    function destroy(args) {
        return autoCompleteObj.destroy();
    }
    function write(args) {
        var treeGridObj = document.getElementById("TreeGrid").ej2_instances[0];
        autoCompleteObj = new ej.dropdowns.AutoComplete({
            dataSource: treeGridObj.grid.dataSource,
            fields: { value: 'TaskName' },
            value: args.rowData[args.column.field]
        });
        autoCompleteObj.appendTo(elem);

    }
</script>
public IActionResult Index()
{
    var tree = TreeData.GetDefaultData();
    ViewBag.datasource = tree;
    return View();
}

Dialog 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 EditSettings as Dialog 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 dialog template will help you to customize the default edit dialog.

In the following sample, treegrid enabled with dialog template editing.

@using Syncfusion.EJ2.Grids

@(Html.EJS().TreeGrid("TreeGrid").DataSource((IEnumerable<object>)ViewBag.datasource)
      .EditSettings(edit =>
       {
        edit.AllowAdding(true);
        edit.AllowDeleting(true);
        edit.AllowEditing(true);
        edit.Mode(Syncfusion.EJ2.TreeGrid.EditMode.Dialog);
        edit.Template("#dialogtemplate");

       })
       .Toolbar(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" })
       .Columns(col =>
        {
          col.Field("TaskId").HeaderText("Task ID").IsPrimaryKey(true).Width(120)
             .TextAlign(TextAlign.Right).Add();
          col.Field("TaskName").HeaderText("Task Name").Add();
          col.Field("StartDate").HeaderText("Start Date").Width(150).Format("yMd")
             .EditType("datepickeredit").TextAlign(TextAlign.Right).Add();
           col.Field("Duration").HeaderText("Duration").Width("110").EditType("numericedit")
              .Edit(new { @params = new { format = "n" } }).TextAlign(TextAlign.Right).Add();

        }).Height(400).ChildMapping("Children").TreeColumnIndex(1).ActionComplete("actionComplete").Render())

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

<script id="dialogtemplate" type="text/x-template">
    <div id="dialogTemp">
    </div>
</script>
public IActionResult Index()
{
    var tree = TreeData.GetDefaultData();
    ViewBag.dataSource = tree;
    return View();
}

public ActionResult Editpartial(TreeData value,bool isedit)
{
    ViewBag.prioritydata = new List<object>() { 
        new { text = "Normal", value= "Normal"},
        new { text = "Critical", value= "Critical"},
        new { text = "Low", value= "Low"},
        new { text = "High", value= "High"},
    };
    return PartialView("editpartial", value);
}
@model TestApplication.Models.TreeData

@*//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="TaskId" value=@Model.TaskId.ToString() disabled type='text' name="TaskId" />
                <span class="e-float-line"></span>
                <label asp-for="TaskId" class="e-float-text e-label-top">Task ID</label>
            </div>
        </div>
        <div class="form-group col-md-6">
            <div class="e-float-input e-control-wrapper">
                <input asp-for="TaskName" name="TaskName" value=@Model.TaskName />
                <span class="e-float-line"></span>
                <label asp-for="TaskName" class="e-float-text e-label-top">Task Name</label>
            </div>
        </div>
    </div>

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

    <div class="form-row">
        <div class="form-group col-md-12">
            <ejs-checkbox checked="@Model.Approved" label="Approved" id="Approved"></ejs-checkbox>
        </div>
    </div>
</div>

<ejs-scripts></ejs-scripts>
@model MVCApplication.Models.TreeGridData
@*//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 value=@Model.TaskId name="TaskId" disabled type='text' />
                <span class="e-float-line"></span>
                <label asp-for="TaskId" class="e-float-text e-label-top">Task ID</label>
            </div>
        </div>
        <div class="form-group col-md-6">
            <div class="e-float-input e-control-wrapper">
                <input name="TaskName" value=@Model.TaskName.ToString() />
                <span class="e-float-line"></span>
                <label asp-for="TaskName" class="e-float-text e-label-top">Task Name</label>
            </div>
        </div>
    </div>

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

    <div class="form-row">
        <div class="form-group col-md-12">
            @Html.EJS().CheckBox("Approved").Checked(Model.Approved).Label("Approved").Render()
        </div>
    </div>
</div>

@Html.EJS().ScriptManager()
public class TreeData
    {
        public TreeData() { }

        public int TaskId { get; set; }

        public string TaskName { get; set; }

        public DateTime StartDate { get; set; }

        public DateTime EndDate { get; set; }

        public int Duration { get; set; }

        public int Progress { get; set; }
        public string Priority { get; set; }
        public bool Approved { get; set; }

        public DateTime FilterStartDate { get; set; }
        public DateTime FilterEndDate { get; set; }

        public List<TreeData> Children { get; set; }

        public int? ParentId { get; set; }
    }

NOTE

The template form editors should have name attribute.

Get value from editor

You can read, format, and update the current editor value in the ActionBegin event at the time of setting requestType to save.

In the following code example, the progress value has been formatted and updated.

    function actionBegin(args) {
        if (args.requestType === 'save') {
            // cast string to integer value.
            args.data['progress'] = parseFloat(args.form.querySelector("#progress").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('taskName')as HTMLInputElement).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: DialogEditEventArgs) {
        if ((args.requestType === 'beginEdit' || args.requestType === 'add')) {
            // Add Validation Rules
            args.form.ej2_instances[0].addRules('progress', {max: 100});
        }
    }

NOTE

You can refer to our ASP.NET MVC Tree Grid feature tour page for its groundbreaking feature representations. You can also explore our ASP.NET MVC Tree Grid example to knows how to present and manipulate data.