The TreeGrid component has options to dynamically insert, delete and update records.
Editing feature is enabled by using e-treegrid-editSettings
tag helper and it requires a primary key column for CRUD operations.
To define the primary key, set isPrimaryKey
of e-treegrid-column
tag helper to true in particular column.
<ejs-treegrid id="TreeGrid" dataSource="@ViewBag.datasource" childMapping="Children" height="270" treeColumnIndex="1">
<e-treegrid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true" mode="Cell"></e-treegrid-editSettings>
<e-treegrid-columns>
<e-treegrid-column field="TaskId" headerText="Task ID" isPrimaryKey="true" textAlign="Right" width="90"></e-treegrid-column>
<e-treegrid-column field="TaskName" headerText="Task Name" width="60"></e-treegrid-column>
<e-treegrid-column field="Priority" headerText="Priority" width="120"></e-treegrid-column>
<e-treegrid-column field="Duration" headerText="Duration" textAlign="Right" width="120"></e-treegrid-column>
</e-treegrid-columns>
</ejs-treegrid>
public IActionResult Index()
{
var tree = TreeData.GetDefaultData();
ViewBag.datasource = tree;
return View();
}
You can disable editing for a particular column, by specifying
allowEditing
ofe-treegrid-column
tag helper to false.
The treegrid toolbar has the built-in items to execute Editing actions.
You can define this by using the toolbar
property.
<ejs-treegrid id="TreeGrid" dataSource="@ViewBag.datasource" childMapping="Children" height="270" treeColumnIndex="1" toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Cancel", "Update" })">
<e-treegrid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true" mode="Row"></e-treegrid-editSettings>
<e-treegrid-columns>
<e-treegrid-column field="TaskId" headerText="Task ID" isPrimaryKey="true" textAlign="Right" width="90"></e-treegrid-column>
<e-treegrid-column field="TaskName" headerText="Task Name" width="60"></e-treegrid-column>
<e-treegrid-column field="Priority" headerText="Priority" width="120"></e-treegrid-column>
<e-treegrid-column field="Duration" headerText="Duration" textAlign="Right" width="120"></e-treegrid-column>
</e-treegrid-columns>
</ejs-treegrid>
public IActionResult Index()
{
var tree = TreeData.GetDefaultData();
ViewBag.datasource = tree;
return View();
}
The editType
of e-treegrid-column
tag helper is used to customize the edit type of the particular column.
You can set the editType
based on data type of the column.
numericedit
- NumericTextBox
component for integers, double, and decimal data types.defaultedit
- TextBox
component for string data type.dropdownedit
- DropDownList
component for list data type.booleanedit
- CheckBox
component for boolean data type.datepickeredit
- DatePicker
component for date data type.datetimepickeredit
- DateTimePicker
component for date time data type.Also, you can customize model of the editType
component through the params in edit
property of e-treegrid-column
tag helper .
The following table describes cell edit type component and their corresponding edit params of the column.
Component | Example |
---|---|
NumericTextBox |
params: { decimals: 2, value: 5 } |
TextBox |
- |
DropDownList |
params: { value: ‘Germany’ } |
Checkbox |
params: { checked: true} |
DatePicker |
params: { format:‘dd.MM.yyyy’ } |
DateTimePicker |
params: { value: new Date() } |
@{
var numParams = new { @params = new { format = "n" } };
var dateParams = new { @params = new { format = "M/d/y hh:mm a" } };
}
<ejs-treegrid id="TreeGrid" dataSource="@ViewBag.datasource" childMapping="Children" load="load" height="270" treeColumnIndex="1" toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Cancel", "Update" })">
<e-treegrid-editSettings allowAdding="true" allowDeleting="true" allowEditing="true" mode="Row"></e-treegrid-editSettings>
<e-treegrid-columns>
<e-treegrid-column field="TaskId" headerText="Task ID" isPrimaryKey="true" textAlign="Right" width="90"></e-treegrid-column>
<e-treegrid-column field="TaskName" headerText="Task Name" editType="stringedit" width="120"></e-treegrid-column>
<e-treegrid-column field="StartDate" headerText="Start Date" edit=dateParams editType="datetimepickeredit" textAlign="Right" width="120"></e-treegrid-column>
<e-treegrid-column field="Approved" headerText="Approved" editType="booleanedit"
type="boolean" displayAsCheckBox="true" textAlign="Center" width="120"></e-treegrid-column>
<e-treegrid-column field="Progress" headerText="Progress" edit=numParams editType="numericedit" textAlign="Right" width="80"></e-treegrid-column>
<e-treegrid-column field="Priority" headerText="Priority" editType="dropdownedit" width="120"></e-treegrid-column>
</e-treegrid-columns>
</ejs-treegrid>
<script>
function load(args) {
this.columns[2].format = { format: 'M/d/y hh:mm a', type: 'dateTime' };
}
</script>
public IActionResult Index()
{
var tree = TreeData.GetDefaultData();
ViewBag.datasource = tree;
return View();
}
If edit type is not defined in the column, then it will be considered as the stringedit type (Textbox component).
The cell edit template is used to add a custom component for a particular column by invoking the following functions:
<ejs-treegrid id="TreeGrid" dataSource="@ViewBag.datasource" height="400" childMapping="Children" treeColumnIndex="1" toolbar="@(new List<string>() { "Add", "Delete", "Update", "Cancel" })">
<e-treegrid-editsettings allowAdding="true" allowEditing="true" allowDeleting="true" mode="Cell" newRowPosition="Below"></e-treegrid-editsettings>
<e-treegrid-columns>
<e-treegrid-column field="TaskId" headerText="Task ID" isPrimaryKey="true" textAlign="Right" width="100"></e-treegrid-column>
<e-treegrid-column field="TaskName" headerText="Task Name" editType="stringedit" width="190" edit="@(new { create = "create", read = "read", write = "write", destroy ="destroy" })"></e-treegrid-column>
<e-treegrid-column field="StartDate" headerText="Start Date" editType="datepickeredit" textAlign="Right" format="yMd" type="date" width="130"></e-treegrid-column>
<e-treegrid-column field="Duration" headerText="Duration" editType="numericedit" textAlign="Right" width="120"></e-treegrid-column>
</e-treegrid-columns>
</ejs-treegrid>
<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();
}
TreeGrid supports the following types of edit modes, they are:
In Cell edit mode, when you double click on a cell, it is changed to edit state.
You can change the cell value and save to the data source.
To enable Cell edit, set the mode
property of e-treegrid-editsettings
tag helper as Cell.
<ejs-treegrid id="TreeGrid" dataSource="@ViewBag.dataSource" height="400" childMapping="Children" treeColumnIndex="1" toolbar="@(new List<string>() { "Add", "Delete", "Update", "Cancel" })">
<e-treegrid-editsettings allowAdding="true" allowEditing="true" allowDeleting="true" mode="Cell"></e-treegrid-editsettings>
<e-treegrid-columns>
<e-treegrid-column field="TaskId" headerText="Task ID" isPrimaryKey="true" textAlign="Right" width="100"></e-treegrid-column>
<e-treegrid-column field="TaskName" headerText="Task Name" editType="stringedit" width="190"></e-treegrid-column>
<e-treegrid-column field="StartDate" headerText="Start Date" editType="datepickeredit" textAlign="Right" format="yMd" type="date" width="130"></e-treegrid-column>
<e-treegrid-column field="Duration" headerText="Duration" editType="numericedit" textAlign="Right" width="120"></e-treegrid-column>
</e-treegrid-columns>
</ejs-treegrid>
public IActionResult Index()
{
var tree = TreeData.GetDefaultData();
ViewBag.dataSource = tree;
return View();
}
Cell edit mode is default mode of editing.
In Row edit mode, when you start editing the currently selected record, the entire row is changed to edit state.
You can change the cell values of the row and save edited data to the data source.
To enable Row edit, set the mode
property of e-treegrid-editsettings
tag helper as Row.
<ejs-treegrid id="TreeGrid" dataSource="@ViewBag.datasource" height="400" childMapping="Children" treeColumnIndex="1" toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" })">
<e-treegrid-editsettings allowAdding="true" allowEditing="true" allowDeleting="true" mode="Row"></e-treegrid-editsettings>
<e-treegrid-columns>
<e-treegrid-column field="TaskId" headerText="Task ID" isPrimaryKey="true" textAlign="Right" width="100"></e-treegrid-column>
<e-treegrid-column field="TaskName" headerText="Task Name" editType="stringedit" width="190"></e-treegrid-column>
<e-treegrid-column field="StartDate" headerText="Start Date" editType="datepickeredit" textAlign="Right" format="yMd" type="date" width="130"></e-treegrid-column>
<e-treegrid-column field="Duration" headerText="Duration" editType="numericedit" textAlign="Right" width="120"></e-treegrid-column>
</e-treegrid-columns>
</ejs-treegrid>
public IActionResult Index()
{
var tree = TreeData.GetDefaultData();
ViewBag.datasource = tree;
return View();
}
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-treegrid-editsettings
tag helper as Dialog.
<ejs-treegrid id="TreeGrid" dataSource="@ViewBag.datasource" height="400" childMapping="Children" treeColumnIndex="1" toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" })">
<e-treegrid-editsettings allowAdding="true" allowEditing="true" allowDeleting="true" mode="Dialog"></e-treegrid-editsettings>
<e-treegrid-columns>
<e-treegrid-column field="TaskId" headerText="Task ID" isPrimaryKey="true" textAlign="Right" width="100"></e-treegrid-column>
<e-treegrid-column field="TaskName" headerText="Task Name" editType="stringedit" width="190"></e-treegrid-column>
<e-treegrid-column field="StartDate" headerText="Start Date" editType="datepickeredit" textAlign="Right" format="yMd" type="date" width="130"></e-treegrid-column>
<e-treegrid-column field="Duration" headerText="Duration" editType="numericedit" textAlign="Right" width="120"></e-treegrid-column>
</e-treegrid-columns>
</ejs-treegrid>
public IActionResult Index()
{
var tree = TreeData.GetDefaultData();
ViewBag.datasource = tree;
return View();
}
In Batch edit mode, when you double-click on the treegrid cell, the target cell goes into edit state.
You can bulk save (added, changed and deleted data in the single request) to data source by clicking on the toolbar’s Update button or by externally invoking the batchSave
method.
To enable Batch edit, set the EditSettings.mode
as Batch.
<ejs-treegrid id="TreeGrid" dataSource="ViewBag.dataSource" height="400" idMapping="TaskId" parentIdMapping="ParentId" treeColumnIndex="1" toolbar="@(new List<string>() { "Add", "Delete", "Update", "Cancel" })">
<e-treegrid-editsettings allowAdding="true" allowEditing="true" allowDeleting="true" mode="Batch" newRowPosition="Below"></e-treegrid-editsettings>
<e-treegrid-columns>
<e-treegrid-column field="TaskId" headerText="Task ID" isPrimaryKey="true" validationRules="@(new { required=true, number=true})" textAlign="Right" width="90"></e-treegrid-column>
<e-treegrid-column field="TaskName" headerText="Task Name" validationRules="@(new { required=true})" editType="stringedit" width="220"></e-treegrid-column>
<e-treegrid-column field="StartDate" headerText=" Start Date" validationRules="@(new { date=true})" editType="datepickeredit" textAlign="Right" format="yMd" type="date" width="130"></e-treegrid-column>
<e-treegrid-column field="Duration" headerText="Duration" validationRules="@(new { number = true, min = 0 })" editType="numericedit" textAlign="Right" edit="@(new { @params = new { format = "n" } })" width="100"></e-treegrid-column>
<e-treegrid-column field="Progress" headerText="Progress" textAlign="Right" width="80" editType="numericedit" validationRules="@(new { number = true, min = 0 })" edit="@(new { @params = new { format = "n" } })"></e-treegrid-column>
<e-treegrid-column field="Priority" headerText="Priority" width="90" editType="stringedit" validationRules="@(new { required=true})"></e-treegrid-column>
</e-treegrid-columns>
</ejs-treegrid>
public IActionResult Index()
{
var tree = TreeData.GetDefaultData();
ViewBag.dataSource = tree;
return View();
}
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
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.
<ejs-treegrid id="TreeGrid" dataSource="@ViewBag.dataSource" height="400" actionComplete="actionComplete" childMapping="Children" treeColumnIndex="1" toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" })">
<e-treegrid-editsettings allowAdding="true" allowEditing="true" allowDeleting="true" mode="Dialog" template="#dialogtemplate"></e-treegrid-editsettings>
<e-treegrid-columns>
<e-treegrid-column field="TaskId" headerText="Task ID" isPrimaryKey="true" textAlign="Right" width="100"></e-treegrid-column>
<e-treegrid-column field="TaskName" headerText="Task Name" editType="stringedit" width="190"></e-treegrid-column>
<e-treegrid-column field="StartDate" headerText="Start Date" textAlign="Right" format="yMd" type="date" width="130"></e-treegrid-column>
<e-treegrid-column field="Duration" headerText="Duration" textAlign="Right" width="120"></e-treegrid-column>
</e-treegrid-columns>
</ejs-treegrid>
<script id='dialogtemplate' type="text/x-template">
<div id="dialogTemp"></div>
</script>
<script>
function actionComplete(args) {
if (args.requestType === 'beginEdit' || args.requestType === 'add') {
var ajax = new ej.base.Ajax({
url: "/Home/EditPartial", //render the partial view
type: "POST",
contentType: "application/json",
data: JSON.stringify({ value: args.rowData, isedit: args.requestType === 'beginEdit' })
});
ajax.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>
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; }
}
The template form editors should have name attribute.
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);
}
}
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();
}
}
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});
}
}
The TreeGrid control provides the support to add the new row in the top, bottom, above selected row, below selected row and child position of tree grid content using newRowPosition
property of e-treegrid-editsettings
tag helper. By default, a new row will be added at the top of the treegrid.
The following examples shows how to set new row position as Child in treegrid.
<ejs-treegrid id="TreeGrid" dataSource="@ViewBag.dataSource" height="400" childMapping="Children"
treeColumnIndex="1" toolbar="@(new List<string>() { "Add", "Delete", "Update", "Cancel" })">
<e-treegrid-editsettings allowAdding="true" allowEditing="true" allowDeleting="true" newRowPosition="Child"></e-treegrid-editsettings>
<e-treegrid-columns>
<e-treegrid-column field="TaskId" headerText="Task ID" isPrimaryKey="true" textAlign="Right" width="70"></e-treegrid-column>
<e-treegrid-column field="TaskName" headerText="Task Name" editType="stringedit" width="180"></e-treegrid-column>
<e-treegrid-column field="StartDate" headerText="Start Date" editType="datetimepickeredit" textAlign="Right" width="185" format="yMd"></e-treegrid-column>
<e-treegrid-column field="Priority" headerText="Priority" defaultValue='Normal' width="100"></e-treegrid-column>
</e-treegrid-columns>
</ejs-treegrid>
public IActionResult Index()
{
var tree = TreeData.GetDefaultData();
ViewBag.dataSource = tree;
return View();
}
The command column provides an option to add CRUD action buttons in a column. This can be defined by the commands
property of e-treegrid-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. |
@{
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-treegrid id="TreeGrid" dataSource="@ViewBag.dataSource" height="400" childMapping="Children" treeColumnIndex="1">
<e-treegrid-editsettings allowAdding="true" allowEditing="true" allowDeleting="true" mode="Row"></e-treegrid-editsettings>
<e-treegrid-columns>
<e-treegrid-column field="TaskId" headerText="Task ID" isPrimaryKey="true" textAlign="Right" width="100"></e-treegrid-column>
<e-treegrid-column field="TaskName" headerText="Task Name" editType="stringedit" width="190"></e-treegrid-column>
<e-treegrid-column field="Duration" headerText="Duration" textAlign="Right" width="120"></e-treegrid-column>
<e-treegrid-column headerText="Manage Records" width="120" commands=commands></e-treegrid-column>
</e-treegrid-columns>
</ejs-treegrid>
public IActionResult Index()
{
var tree = TreeData.GetDefaultData();
ViewBag.dataSource = tree;
return View();
}
The custom command buttons can be added in a column by using the commands
property of e-treegrid-column
tag helper and
the action for the custom buttons can be defined in the Click event of an Button Option.
@{
List<object> commands = new List<object>();
commands.Add(new { type = "taskstatus", buttonOption = new { content = "Details", cssClass = "e-flat e-details" } }); // custom
}
<script>
function load() {
this.columns[3].commands[0].buttonOption.click = function (args) { //click event for custom command button
var treegrid = document.getElementById('TreeGrid').ej2_instances[0]; // treegrid instance
var rowObj= treegrid.grid.getRowObjectFromUID(ej.base.closest(args.target, '.e-row').getAttribute('data-uid'));
alert(JSON.stringify(rowObj.data)); // display row data
}
}
</script>
<ejs-treegrid id="TreeGrid" dataSource="@ViewBag.dataSource" height="400" childMapping="Children" treeColumnIndex="1" load="load">
<e-treegrid-editsettings allowAdding="true" allowEditing="true" allowDeleting="true" mode="Row"></e-treegrid-editsettings>
<e-treegrid-columns>
<e-treegrid-column field="TaskId" headerText="Task ID" isPrimaryKey="true" textAlign="Right" width="100"></e-treegrid-column>
<e-treegrid-column field="TaskName" headerText="Task Name" editType="stringedit" width="190"></e-treegrid-column>
<e-treegrid-column field="Duration" headerText="Duration" textAlign="Right" width="120"></e-treegrid-column>
<e-treegrid-column headerText="Manage Records" width="120" commands=commands></e-treegrid-column>
</e-treegrid-columns>
</ejs-treegrid>
public IActionResult Index()
{
var tree = TreeData.GetDefaultData();
ViewBag.dataSource = tree;
return View();
}
The delete confirm dialog can be shown when deleting a record by defining the showDeleteConfirmDialog
as true.
<ejs-treegrid id="TreeGrid" dataSource="@ViewBag.dataSource" height="400" childMapping="Children" treeColumnIndex="1" toolbar="@(new List<string>() { "Add", "Delete", "Update", "Cancel" })">
<e-treegrid-editsettings allowAdding="true" allowEditing="true" allowDeleting="true" showDeleteConfirmDialog="true" mode="Cell"></e-treegrid-editsettings>
<e-treegrid-columns>
<e-treegrid-column field="TaskId" headerText="Task ID" isPrimaryKey="true" textAlign="Right" width="100"></e-treegrid-column>
<e-treegrid-column field="TaskName" headerText="Task Name" editType="stringedit" width="190"></e-treegrid-column>
<e-treegrid-column field="StartDate" headerText="Start Date" editType="datepickeredit" textAlign="Right" format="yMd" type="date" width="130"></e-treegrid-column>
<e-treegrid-column field="Duration" headerText="Duration" editType="numericedit" textAlign="Right" width="120"></e-treegrid-column>
</e-treegrid-columns>
</ejs-treegrid>
public IActionResult Index()
{
var tree = TreeData.GetDefaultData();
ViewBag.dataSource = tree;
return View();
}
The showDeleteConfirmDialog supports all type of edit modes.
Column validation allows you to validate the edited or added row data and it display errors for invalid fields before saving data. TreeGrid uses Form Validator component for column validation.
You can set validation rules by defining the validationRules
in e-treegrid-column
tag helper.
@{
var dict = new Dictionary<string, object>();
dict.Add("required", true);
dict.Add("min", 0);
}
<ejs-treegrid id="TreeGrid" dataSource="@ViewBag.dataSource" height="400" childMapping="Children" treeColumnIndex="1" toolbar="@(new List<string>() { "Add", "Delete", "Update", "Cancel" })">
<e-treegrid-editsettings allowAdding="true" allowEditing="true" allowDeleting="true"></e-treegrid-editsettings>
<e-treegrid-columns>
<e-treegrid-column field="TaskId" headerText="Task ID" isPrimaryKey="true" validationRules="@(new { required=true, number=true})" textAlign="Right" width="70"></e-treegrid-column>
<e-treegrid-column field="TaskName" headerText="Task Name" validationRules="@(new { required=true})" editType="stringedit" width="180"></e-treegrid-column>
<e-treegrid-column field="StartDate" headerText="Start Date" validationRules="@(new { date=true})" editType="datetimepickeredit" textAlign="Right" width="185" format="yMd"></e-treegrid-column>
<e-treegrid-column field="Approved" headerText="Approved" editType="booleanedit" textAlign="Center" width="80" displayAsCheckbox="true" type="boolean"></e-treegrid-column>
<e-treegrid-column field="Progress" headerText="Progress" validationRules="@(dict)" editType="numericedit" textAlign="Right" width="100"></e-treegrid-column>
<e-treegrid-column field="Priority" headerText="Priority" editType="dropdownedit" validationRules="@(new { required=true})" width="100"></e-treegrid-column>
</e-treegrid-columns>
</ejs-treegrid>
public IActionResult Index()
{
var tree = TreeData.GetDefaultData();
ViewBag.dataSource = tree;
return View();
}
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 Priority column.
@{
var dict = new Dictionary<string, object>();
dict.Add("require", true);
}
<ejs-treegrid id="TreeGrid" dataSource="@ViewBag.dataSource" height="400" childMapping="Children" treeColumnIndex="1" toolbar="@(new List<string>() { "Add", "Delete", "Update", "Cancel" })" load="load">
<e-treegrid-editsettings allowAdding="true" allowEditing="true" allowDeleting="true"></e-treegrid-editsettings>
<e-treegrid-columns>
<e-treegrid-column field="TaskId" headerText="Task ID" isPrimaryKey="true" validationRules="@(new { required = true, number = true})" textAlign="Right" width="70"></e-treegrid-column>
<e-treegrid-column field="TaskName" headerText="Task Name" editType="stringedit" width="180"></e-treegrid-column>
<e-treegrid-column field="StartDate" headerText="Start Date" validationRules="@(new { date = true})" format="yMd" editType="datetimepickeredit" textAlign="Right" width="185"></e-treegrid-column>
<e-treegrid-column field="Priority" headerText="Priority" validationRules="@(dict)" width="100"></e-treegrid-column>
</e-treegrid-columns>
</ejs-treegrid>
<script>
function load() {
this.columns[1].validationRules = { required: true, min: [customFn, 'Value should be greater than 5 letters'] };
}
function customFn(args) {
return args['value'].length >= 5;
}
</script>
public IActionResult Index()
{
var tree = TreeData.GetDefaultData();
ViewBag.dataSource = tree;
return View();
}
Edited data can be persisted in the database using the RESTful web services.
All the CRUD operations in the treegrid 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 following section, we have explained how to perform CRUD operation in server-side using the UrlAdaptor and RemoteSave 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 and BatchUrl.
The following code example describes the above behavior.
<ejs-treegrid id="TreeGrid" height="400" idMapping="TaskId" hasChildMapping="isParent" parentIdMapping='ParentId' treeColumnIndex="1" toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" })">
<e-data-manager url="/Home/DataSource" insertUrl="/Home/Insert" updateUrl="/Home/Update" removeUrl="/Home/Remove" adaptor="UrlAdaptor"></e-data-manager>
<e-treegrid-editsettings allowAdding="true" allowEditing="true" allowDeleting="true" mode="Row" newRowPosition="Below"></e-treegrid-editsettings>
<e-treegrid-columns>
<e-treegrid-column field="TaskId" headerText="Task ID" isPrimaryKey="true" textAlign="Right" width="70"></e-treegrid-column>
<e-treegrid-column field="TaskName" headerText="Task Name" editType="stringedit" width="180"></e-treegrid-column>
<e-treegrid-column field="StartDate" headerText="Start Date" editType="datetimepickeredit" format="yMd" textAlign="Right" width="185"></e-treegrid-column>
<e-treegrid-column field="Priority" headerText="Priority" defaultValue="Normal" width="100"></e-treegrid-column>
</e-treegrid-columns>
</ejs-treegrid>
public IActionResult DataSource([FromBody]DataManager dm)
{
var DataSource = TreeData.GetTree();
var count = DataSource.ToList<TreeData>().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.
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.
<ejs-treegrid id="TreeGrid" height="400" idMapping="TaskId" hasChildMapping="isParent" parentIdMapping='ParentId' treeColumnIndex="1" toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" })">
<e-data-manager url="/Home/DataSource" insertUrl="/Home/Insert" updateUrl="/Home/Update" removeUrl="/Home/Remove" adaptor="UrlAdaptor"></e-data-manager>
<e-treegrid-editsettings allowAdding="true" allowEditing="true" allowDeleting="true" mode="Row" newRowPosition="Below"></e-treegrid-editsettings>
<e-treegrid-columns>
<e-treegrid-column field="TaskId" headerText="Task ID" isPrimaryKey="true" textAlign="Right" width="70"></e-treegrid-column>
<e-treegrid-column field="TaskName" headerText="Task Name" editType="stringedit" width="180"></e-treegrid-column>
<e-treegrid-column field="StartDate" headerText="Start Date" editType="datetimepickeredit" format="yMd" textAlign="Right" width="185"></e-treegrid-column>
<e-treegrid-column field="Priority" headerText="Priority" defaultValue="Normal" width="100"></e-treegrid-column>
</e-treegrid-columns>
</ejs-treegrid>
public void Insert([FromBody]ICRUDModel value)
{
var i = 0;
var index = value.rowIndex;
for (; i < TreeData.tree.Count; i++)
{
if (TreeData.tree[i].TaskID == index)
{
break;
}
}
i += FindChildRecords(index);
TreeData.tree.Insert(i + 1, value.value);
}
public int FindChildRecords(int? id)
{
var count = 0;
for (var i = 0; i < TreeData.tree.Count; i++)
{
if (TreeData.tree[i].ParentItem == id)
{
count++;
count += FindChildRecords(TreeData.tree[i].TaskID);
}
}
return count;
}
public class CustomBind : TreeData
{
public TreeData parentItem;
}
public class ICRUDModel
{
public CustomBind value;
public int key;
public string action;
public int? relationalKey;
}
The newly added record details are bound to the value parameter and relationalKey contains primaryKey value of an selected record helps to find out the position of newly added record. Please refer to the following screenshot.
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.
<ejs-treegrid id="TreeGrid" height="400" idMapping="TaskId" hasChildMapping="isParent" parentIdMapping='ParentId' treeColumnIndex="1" toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" })">
<e-data-manager url="/Home/DataSource" insertUrl="/Home/Insert" updateUrl="/Home/Update" removeUrl="/Home/Remove" adaptor="UrlAdaptor"></e-data-manager>
<e-treegrid-editsettings allowAdding="true" allowEditing="true" allowDeleting="true" mode="Row" newRowPosition="Below"></e-treegrid-editsettings>
<e-treegrid-columns>
<e-treegrid-column field="TaskId" headerText="Task ID" isPrimaryKey="true" textAlign="Right" width="70"></e-treegrid-column>
<e-treegrid-column field="TaskName" headerText="Task Name" editType="stringedit" width="180"></e-treegrid-column>
<e-treegrid-column field="StartDate" headerText="Start Date" editType="datetimepickeredit" format="yMd" textAlign="Right" width="185"></e-treegrid-column>
<e-treegrid-column field="Priority" headerText="Priority" defaultValue="Normal" width="100"></e-treegrid-column>
</e-treegrid-columns>
</ejs-treegrid>
public ActionResult Update([FromBody]CRUDModel value)
{
var val = TreeData.tree.Where(ds => ds.TaskID == value.Value.TaskID).FirstOrDefault();
val.TaskName = value.Value.TaskName;
val.StartDate = value.Value.StartDate;
val.Duration = value.Value.Duration;
val.Priority = value.Value.Priority;
val.Progress = value.Value.Progress;
return Json(val);
}
public class CRUDModel
{
public List<TreeData> Added { get; set; }
public List<TreeData> Changed { get; set; }
public List<TreeData> Deleted { get; set; }
public TreeData Value;
public int Key;
public int? RelationalKey;
}
The updated record details are bound to the value parameter. Please refer to the following screenshot.
Using the RemoveUrl and BatchUrl 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.
<ejs-treegrid id="TreeGrid" height="400" idMapping="TaskId" hasChildMapping="isParent" parentIdMapping='ParentId' treeColumnIndex="1" toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" })">
<e-data-manager url="/Home/DataSource" insertUrl="/Home/Insert" updateUrl="/Home/Update" removeUrl="/Home/Remove" adaptor="UrlAdaptor"></e-data-manager>
<e-treegrid-editsettings allowAdding="true" allowEditing="true" allowDeleting="true" mode="Row" newRowPosition="Below"></e-treegrid-editsettings>
<e-treegrid-columns>
<e-treegrid-column field="TaskId" headerText="Task ID" isPrimaryKey="true" textAlign="Right" width="70"></e-treegrid-column>
<e-treegrid-column field="TaskName" headerText="Task Name" editType="stringedit" width="180"></e-treegrid-column>
<e-treegrid-column field="StartDate" headerText="Start Date" editType="datetimepickeredit" format="yMd" textAlign="Right" width="185"></e-treegrid-column>
<e-treegrid-column field="Priority" headerText="Priority" defaultValue="Normal" width="100"></e-treegrid-column>
</e-treegrid-columns>
</ejs-treegrid>
public void Remove([FromBody]CRUDModel value)
{
TreeData.tree.Remove(TreeData.tree.Where(ds => ds.TaskID == int.Parse(value.Key.ToString())).FirstOrDefault());
}
public ActionResult Delete(CRUDModel value)
{
if (value.Deleted != null)
{
for (var i = 0; i < value.Deleted.Count().Count; i++)
{
TreeData.tree.Remove(TreeData.tree.Where(ds => ds.TaskID == value.Deleted[i].TaskID).FirstOrDefault());
}
}
}
public class CRUDModel
{
public List<TreeData> Added { get; set; }
public List<TreeData> Changed { get; set; }
public List<TreeData> Deleted { get; set; }
public TreeData Value;
public int Key;
public int? RelationalKey;
}
The deleted record primary key value is bound to the key parameter. Please refer to the following screenshot.
While delete parent record, the parent and child records is bound to the deleted parameter. Please refer to the following screenshot.
You may need to perform all Tree Grid Actions in client-side except the CRUD operations, that should be interacted with server-side to persist data. It can be achieved in TreeGrid by using RemoteSaveAdaptor.
Datasource must be set to json property and set RemoteSaveAdaptor to the adaptor property. CRUD operations can be mapped to server-side using updateUrl, insertUrl, removeUrl and batchUrl properties.
You can use the following code example to use RemoteSaveAdaptor in TreeGrid.
<ejs-treegrid id="TreeGrid" hasChildMapping="isParent" idMapping="TaskID" parentIdMapping="parentItem" treeColumnIndex="1" allowPaging="true" toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" })">
<e-data-manager json ="@ViewBag.dataSource" insertUrl="/Home/Insert" updateUrl="/Home/Update" removeUrl="/Home/Remove" batchUrl="/Home/Delete" adaptor="RemoteSaveAdaptor"></e-data-manager>
<e-treegrid-editsettings allowAdding="true" allowEditing="true" allowDeleting="true" newRowPosition="Below" mode="Row"></e-treegrid-editsettings>
<e-treegrid-columns>
<e-treegrid-column field="TaskID" headerText="Task ID" textAlign="Right" width="120"></e-treegrid-column>
<e-treegrid-column field="TaskName" headerText="Task Name" width="150"></e-treegrid-column>
<e-treegrid-column field="Duration" headerText="Duration" textAlign="Right" width="110"></e-treegrid-column>
<e-treegrid-column field="Progress" headerText="Progress" textAlign="Right" width="110"></e-treegrid-column>
</e-treegrid-columns>
</ejs-treegrid>
public ActionResult Index(DataManager dm)
{
var data = TreeData.GetTree();
ViewBag.dataSource = data;
return View();
}
public ActionResult Insert([FromBody]CRUDModel value)
{
var i = 0;
for (; i < TreeData.tree.Count; i++)
{
if (TreeData.tree[i].TaskID == value.RelationalKey)
{
break;
}
}
i += FindChildRecords(value.RelationalKey); // Finds Inserted new record index when newRowPosition API is in "Below".
TreeData.tree.Insert(i + 1, value.Value);
return Json(value.Value);
}
public int FindChildRecords(int? id)
{
var count = 0;
for (var i = 0; i < TreeData.tree.Count; i++)
{
if (TreeData.tree[i].ParentID == id)
{
count++;
count += FindChildRecords(TreeData.tree[i].TaskID);
}
}
return count;
}
public ActionResult Update([FromBody]CRUDModel value)
{
var val = TreeData.tree.Where(ds => ds.TaskID == value.Value.TaskID).FirstOrDefault();
val.TaskName = value.Value.TaskName;
val.StartDate = value.Value.StartDate;
val.Duration = value.Value.Duration;
val.Priority = value.Value.Priority;
val.Progress = value.Value.Progress;
return Json(val);
}
public void Remove([FromBody]CRUDModel value)
{
TreeData.tree.Remove(TreeData.tree.Where(ds => ds.TaskID == int.Parse(value.Key.ToString())).FirstOrDefault());
}
public ActionResult Delete([FromBody]CRUDModel value)
{
if (value.Deleted != null)
{
for (var i = 0; i < value.Deleted.Count().Count; i++)
{
TreeData.tree.Remove(TreeData.tree.Where(ds => ds.TaskID == value.Deleted[i].TaskID).FirstOrDefault());
}
}
}
public class CRUDModel
{
public List<TreeData> Added { get; set; }
public List<TreeData> Changed { get; set; }
public List<TreeData> Deleted { get; set; }
public TreeData Value;
public int Key;
public int? RelationalKey;
}
The treegrid 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
in e-treegrid-column
tag helper.
<ejs-treegrid id="TreeGrid" dataSource="@ViewBag.datasource" height="400" childMapping="Children" treeColumnIndex="1" toolbar="@(new List<string>() { "Add", "Delete", "Update", "Cancel" })">
<e-treegrid-editsettings allowAdding="true" allowEditing="true" allowDeleting="true"></e-treegrid-editsettings>
<e-treegrid-columns>
<e-treegrid-column field="TaskId" headerText="Task ID" isPrimaryKey="true" textAlign="Right" width="70"></e-treegrid-column>
<e-treegrid-column field="TaskName" headerText="Task Name" editType="stringedit" width="180"></e-treegrid-column>
<e-treegrid-column field="StartDate" headerText="Start Date" editType="datetimepickeredit" format="yMd" textAlign="Right" width="185"></e-treegrid-column>
<e-treegrid-column field="Priority" headerText="Priority" defaultValue="Normal" width="100"></e-treegrid-column>
</e-treegrid-columns>
</ejs-treegrid>
public IActionResult Index()
{
var tree = TreeData.GetDefaultData();
ViewBag.datasource = tree;
return View();
}
You can disable editing for particular columns by using the allowEditing
property of e-treegrid-column
tag helper.
In the following demo, editing is disabled for the Start Date column.
<ejs-treegrid id="TreeGrid" dataSource="@ViewBag.dataSource" height="400" childMapping="Children" treeColumnIndex="1" toolbar="@(new List<string>() { "Add", "Delete", "Update", "Cancel" })">
<e-treegrid-editsettings allowAdding="true" allowEditing="true" allowDeleting="true"></e-treegrid-editsettings>
<e-treegrid-columns>
<e-treegrid-column field="TaskId" headerText="Task ID" isPrimaryKey="true" textAlign="Right" width="70"></e-treegrid-column>
<e-treegrid-column field="TaskName" headerText="Task Name" editType="stringedit" width="180"></e-treegrid-column>
<e-treegrid-column field="StartDate" headerText="Start Date" allowEditing="false" editType="datetimepickeredit" format="yMd" textAlign="Right" width="185"></e-treegrid-column>
<e-treegrid-column field="Priority" headerText="Priority" width="100"></e-treegrid-column>
</e-treegrid-columns>
</ejs-treegrid>
public IActionResult Index()
{
var tree = TreeData.GetDefaultData();
ViewBag.dataSource = tree;
return View();
}
The Editing functionalities can be performed based upon the primary key value of the selected row.
If isPrimaryKey
is not defined in the treegrid, then edit or delete action take places the first row.