The TreeGrid component has options to dynamically insert, delete and update records.
Editing feature is enabled by using editSettings
property and it requires a primary key column for CRUD operations.
To define the primary key, set columns.isPrimaryKey
to true
in particular column.
To use CRUD, inject the Edit
module in treegrid.
ej.treegrid.TreeGrid.Inject(ej.treegrid.Edit);
var treeGridObj = new ej.treegrid.TreeGrid({
dataSource: sampleData,
childMapping: 'subtasks',
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Cell' },
treeColumnIndex: 1,
columns: [
{ field: 'taskID', headerText: 'Task ID', isPrimaryKey: true, width: 90, textAlign: 'Right'},
{ field: 'taskName', headerText: 'Task Name', width: 180 },
{ field: 'priority', headerText: 'Priority', width: 90 },
{ field: 'duration', headerText: 'Duration', width: 80, textAlign: 'Right' }
],
height: 270
});
treeGridObj.appendTo('#TreeGrid');
<!DOCTYPE html><html lang="en"><head>
<title>EJ2 Tree Grid</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Typescript Tree Grid Control">
<meta name="author" content="Syncfusion">
<link href="index.css" rel="stylesheet">
<!-- Syncfusion Essential JS 2 Styles -->
<link rel="stylesheet" href="https://cdn.syncfusion.com/ej2/20.1.55/material.css">
<link href="//cdn.syncfusion.com/ej2/20.1.55/ej2-splitbuttons/styles/material.css" rel="stylesheet">
<script src="https://cdn.syncfusion.com/ej2/20.1.55/dist/ej2.min.js" type="text/javascript"></script>
<script src="es5-datasource.js" type="text/javascript"></script>
</head>
<body>
<div id="container">
<div id="TreeGrid"></div>
</div>
<script>
var ele = document.getElementById('container');
if(ele) {
ele.style.visibility = "visible";
}
</script>
<script src="index.js" type="text/javascript"></script>
</body></html>
- You can disable editing for a particular column, by specifying
columns.allowEditing
tofalse
.
The treegrid toolbar has the built-in items to execute Editing actions.
You can define this by using the toolbar
property.
ej.treegrid.TreeGrid.Inject(ej.treegrid.Edit, ej.treegrid.Toolbar);
var treeGridObj = new ej.treegrid.TreeGrid({
dataSource: sampleData,
childMapping: 'subtasks',
toolbar: ['Add', 'Edit', 'Delete', 'Update', 'Cancel'],
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Row' },
treeColumnIndex: 1,
columns: [
{ field: 'taskID', headerText: 'Task ID', isPrimaryKey: true, width: 90, textAlign: 'Right'},
{ field: 'taskName', headerText: 'Task Name', width: 180 },
{ field: 'priority', headerText: 'Priority', width: 90 },
{ field: 'duration', headerText: 'Duration', width: 80, textAlign: 'Right' }
],
height: 270
});
treeGridObj.appendTo('#TreeGrid');
<!DOCTYPE html><html lang="en"><head>
<title>EJ2 Tree Grid</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Typescript Tree Grid Control">
<meta name="author" content="Syncfusion">
<link href="index.css" rel="stylesheet">
<!-- Syncfusion Essential JS 2 Styles -->
<link rel="stylesheet" href="https://cdn.syncfusion.com/ej2/20.1.55/material.css">
<link href="//cdn.syncfusion.com/ej2/20.1.55/ej2-splitbuttons/styles/material.css" rel="stylesheet">
<script src="https://cdn.syncfusion.com/ej2/20.1.55/dist/ej2.min.js" type="text/javascript"></script>
<script src="es5-datasource.js" type="text/javascript"></script>
</head>
<body>
<div id="container">
<div id="TreeGrid"></div>
</div>
<script>
var ele = document.getElementById('container');
if(ele) {
ele.style.visibility = "visible";
}
</script>
<script src="index.js" type="text/javascript"></script>
</body></html>
The columns.editType
is used to customize the edit type of the particular column.
You can set the columns.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 columns.editType
component through the columns.edit.params
.
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() } |
ej.treegrid.TreeGrid.Inject(ej.treegrid.Edit, ej.treegrid.Toolbar);
var treeGridObj = new ej.treegrid.TreeGrid({
dataSource: sampleData,
childMapping: 'subtasks',
toolbar: ['Add', 'Delete', 'Update', 'Cancel'],
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Row' },
treeColumnIndex: 1,
columns: [
{
field: 'taskID', headerText: 'Task ID', isPrimaryKey: true, textAlign: 'Right', width: 100
},
{
field: 'taskName', headerText: 'Task Name', editType: 'stringedit', width: 170
},
{
field: 'startDate', headerText: 'Start Date', textAlign: 'Right', width: 180,
editType: 'datetimepickeredit', edit: { params: { format: 'M/d/y hh:mm a' } },
format: { format: 'M/d/y hh:mm a', type: 'dateTime' }
},
{
field: 'approved', headerText: 'Approved', width: 110, editType: 'booleanedit',
type: 'boolean', displayAsCheckBox: true
},
{
field: 'progress', headerText: 'Progress', textAlign: 'Right', width: 120,
editType: 'numericedit', edit: { params: { format: 'n' } }
},
{ field: 'priority', headerText: 'Priority', width: 110, editType: 'dropdownedit' }
],
height: 270
});
treeGridObj.appendTo('#TreeGrid');
<!DOCTYPE html><html lang="en"><head>
<title>EJ2 Tree Grid</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Typescript Tree Grid Control">
<meta name="author" content="Syncfusion">
<link href="index.css" rel="stylesheet">
<!-- Syncfusion Essential JS 2 Styles -->
<link rel="stylesheet" href="https://cdn.syncfusion.com/ej2/20.1.55/material.css">
<link href="//cdn.syncfusion.com/ej2/20.1.55/ej2-splitbuttons/styles/material.css" rel="stylesheet">
<script src="https://cdn.syncfusion.com/ej2/20.1.55/dist/ej2.min.js" type="text/javascript"></script>
<script src="es5-datasource.js" type="text/javascript"></script>
</head>
<body>
<div id="container">
<div id="TreeGrid"></div>
</div>
<script>
var ele = document.getElementById('container');
if(ele) {
ele.style.visibility = "visible";
}
</script>
<script src="index.js" type="text/javascript"></script>
</body></html>
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:
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.ej.treegrid.TreeGrid.Inject(ej.treegrid.Edit, ej.treegrid.Toolbar);
var elem;
var autoCompleteObj;
var treeGridObj = new ej.treegrid.TreeGrid({
dataSource: sampleData,
childMapping: 'subtasks',
treeColumnIndex: 1,
height: 400,
editSettings: {
allowAdding: true,
allowEditing: true,
allowDeleting: true,
mode: 'Cell',
newRowPosition: 'Below'
},
toolbar: ['Add', 'Delete', 'Update', 'Cancel'],
columns: [
{
field: 'taskID', headerText: 'Task ID', isPrimaryKey: true, textAlign: 'Right', width: 90
},
{ field: 'taskName', headerText: 'Task Name', editType: 'stringedit', edit: {
create: function(){
elem = document.createElement('input');
return elem;
},
read: function() {
return autoCompleteObj.value;
},
destroy: function() {
autoCompleteObj.destroy();
},
write: function(args){
autoCompleteObj = new ej.dropdowns.AutoComplete({
dataSource: treeGridObj.grid.dataSource,
fields: { value: 'taskName' },
value: args.rowData[args.column.field]
});
autoCompleteObj.appendTo(elem);
}
},
width: 180 },
{ field: 'startDate', headerText: 'Start Date', textAlign: 'Right', width: 130, editType: 'datepickeredit', type: 'date', format: 'yMd' },
{
field: 'duration', headerText: 'Duration', textAlign: 'Right', width: 80, editType: 'numericedit', edit: { params: { format: 'n'}}
}
]
});
treeGridObj.appendTo('#TreeGrid');
<!DOCTYPE html><html lang="en"><head>
<title>EJ2 Tree Grid</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Typescript Tree Grid Control">
<meta name="author" content="Syncfusion">
<link href="index.css" rel="stylesheet">
<!-- Syncfusion Essential JS 2 Styles -->
<link rel="stylesheet" href="https://cdn.syncfusion.com/ej2/20.1.55/material.css">
<link href="//cdn.syncfusion.com/ej2/20.1.55/ej2-splitbuttons/styles/material.css" rel="stylesheet">
<script src="https://cdn.syncfusion.com/ej2/20.1.55/dist/ej2.min.js" type="text/javascript"></script>
<script src="es5-datasource.js" type="text/javascript"></script>
</head>
<body>
<div id="container">
<div id="TreeGrid"></div>
</div>
<script>
var ele = document.getElementById('container');
if(ele) {
ele.style.visibility = "visible";
}
</script>
<script src="index.js" type="text/javascript"></script>
</body></html>
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 editSettings.mode
as Cell
.
ej.treegrid.TreeGrid.Inject(ej.treegrid.Edit, ej.treegrid.Toolbar);
var treeGridObj = new ej.treegrid.TreeGrid({
dataSource: sampleData,
childMapping: 'subtasks',
toolbar: ['Add', 'Delete', 'Update', 'Cancel'],
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Cell' },
treeColumnIndex: 1,
columns: [
{ field: 'taskID', headerText: 'Task ID', isPrimaryKey: true, width: 90, textAlign: 'Right'},
{ field: 'taskName', headerText: 'Task Name', width: 180 },
{
field: 'startDate', headerText: 'Start Date', width: 90, textAlign: 'Right', editType: 'datepickeredit', type: 'date', format: 'yMd'
},
{ field: 'duration', headerText: 'Duration', width: 80, textAlign: 'Right' }
],
height: 270
});
treeGridObj.appendTo('#TreeGrid');
<!DOCTYPE html><html lang="en"><head>
<title>EJ2 Tree Grid</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Typescript Tree Grid Control">
<meta name="author" content="Syncfusion">
<link href="index.css" rel="stylesheet">
<!-- Syncfusion Essential JS 2 Styles -->
<link rel="stylesheet" href="https://cdn.syncfusion.com/ej2/20.1.55/material.css">
<link href="//cdn.syncfusion.com/ej2/20.1.55/ej2-splitbuttons/styles/material.css" rel="stylesheet">
<script src="https://cdn.syncfusion.com/ej2/20.1.55/dist/ej2.min.js" type="text/javascript"></script>
<script src="es5-datasource.js" type="text/javascript"></script>
</head>
<body>
<div id="container">
<div id="TreeGrid"></div>
</div>
<script>
var ele = document.getElementById('container');
if(ele) {
ele.style.visibility = "visible";
}
</script>
<script src="index.js" type="text/javascript"></script>
</body></html>
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 editSettings.mode
as Row
.
ej.treegrid.TreeGrid.Inject(ej.treegrid.Edit, ej.treegrid.Toolbar);
var treeGridObj = new ej.treegrid.TreeGrid({
dataSource: sampleData,
childMapping: 'subtasks',
toolbar: ['Add', 'Edit', 'Delete', 'Update', 'Cancel'],
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Row' },
treeColumnIndex: 1,
columns: [
{ field: 'taskID', headerText: 'Task ID', isPrimaryKey: true, width: 90, textAlign: 'Right'},
{ field: 'taskName', headerText: 'Task Name', width: 180 },
{
field: 'startDate', headerText: 'Start Date', width: 90, textAlign: 'Right', editType: 'datepickeredit', type: 'date', format: 'yMd'
},
{ field: 'duration', headerText: 'Duration', width: 80, textAlign: 'Right' }
],
height: 270
});
treeGridObj.appendTo('#TreeGrid');
<!DOCTYPE html><html lang="en"><head>
<title>EJ2 Tree Grid</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Typescript Tree Grid Control">
<meta name="author" content="Syncfusion">
<link href="index.css" rel="stylesheet">
<!-- Syncfusion Essential JS 2 Styles -->
<link rel="stylesheet" href="https://cdn.syncfusion.com/ej2/20.1.55/material.css">
<link href="//cdn.syncfusion.com/ej2/20.1.55/ej2-splitbuttons/styles/material.css" rel="stylesheet">
<script src="https://cdn.syncfusion.com/ej2/20.1.55/dist/ej2.min.js" type="text/javascript"></script>
<script src="es5-datasource.js" type="text/javascript"></script>
</head>
<body>
<div id="container">
<div id="TreeGrid"></div>
</div>
<script>
var ele = document.getElementById('container');
if(ele) {
ele.style.visibility = "visible";
}
</script>
<script src="index.js" type="text/javascript"></script>
</body></html>
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 editSettings.mode
as Dialog
.
ej.treegrid.TreeGrid.Inject(ej.treegrid.Edit, ej.treegrid.Toolbar);
var treeGridObj = new ej.treegrid.TreeGrid({
dataSource: sampleData,
childMapping: 'subtasks',
toolbar: ['Add', 'Edit', 'Delete', 'Update', 'Cancel'],
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Dialog' },
treeColumnIndex: 1,
columns: [
{ field: 'taskID', headerText: 'Task ID', isPrimaryKey: true, width: 90, textAlign: 'Right'},
{ field: 'taskName', headerText: 'Task Name', width: 180 },
{
field: 'startDate', headerText: 'Start Date', width: 90, editType: 'datepickeredit', textAlign: 'Right', type: 'date',format: 'yMd'
},
{ field: 'duration', headerText: 'Duration', width: 80, textAlign: 'Right' }
],
height: 270
});
treeGridObj.appendTo('#TreeGrid');
<!DOCTYPE html><html lang="en"><head>
<title>EJ2 Tree Grid</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Typescript Tree Grid Control">
<meta name="author" content="Syncfusion">
<link href="index.css" rel="stylesheet">
<!-- Syncfusion Essential JS 2 Styles -->
<link rel="stylesheet" href="https://cdn.syncfusion.com/ej2/20.1.55/material.css">
<link href="//cdn.syncfusion.com/ej2/20.1.55/ej2-splitbuttons/styles/material.css" rel="stylesheet">
<script src="https://cdn.syncfusion.com/ej2/20.1.55/dist/ej2.min.js" type="text/javascript"></script>
<script src="es5-datasource.js" type="text/javascript"></script>
</head>
<body>
<div id="container">
<div id="TreeGrid"></div>
</div>
<script>
var ele = document.getElementById('container');
if(ele) {
ele.style.visibility = "visible";
}
</script>
<script src="index.js" type="text/javascript"></script>
</body></html>
In Batch edit mode, when you double-click on the Tree 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 invoking the batchSave
method. To enable Batch edit, set the editSettings.mode
as Batch
.
ej.treegrid.TreeGrid.Inject(ej.treegrid.Edit, ej.treegrid.Toolbar);
var treeGridObj = new ej.treegrid.TreeGrid({
dataSource: projectData,
idMapping: 'TaskID',
parentIdMapping: 'parentID',
toolbar: ['Add', 'Edit', 'Delete', 'Update', 'Cancel'],
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Batch' },
treeColumnIndex: 1,
columns: [
{ field: 'TaskID', headerText: 'Task ID', isPrimaryKey: true, width: 90, textAlign: 'Right'},
{ field: 'TaskName', headerText: 'Task Name', width: 180 },
{
field: 'StartDate', headerText: 'Start Date', width: 90, editType: 'datepickeredit', textAlign: 'Right', type: 'date',format: 'yMd'
},
{ field: 'Duration', headerText: 'Duration', width: 80, textAlign: 'Right' }
],
height: 270
});
treeGridObj.appendTo('#TreeGrid');
<!DOCTYPE html><html lang="en"><head>
<title>EJ2 Tree Grid</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Typescript Tree Grid Control">
<meta name="author" content="Syncfusion">
<link href="index.css" rel="stylesheet">
<!-- Syncfusion Essential JS 2 Styles -->
<link rel="stylesheet" href="https://cdn.syncfusion.com/ej2/20.1.55/material.css">
<link href="//cdn.syncfusion.com/ej2/20.1.55/ej2-splitbuttons/styles/material.css" rel="stylesheet">
<script src="https://cdn.syncfusion.com/ej2/20.1.55/dist/ej2.min.js" type="text/javascript"></script>
<script src="es5-datasource.js" type="text/javascript"></script>
</head>
<body>
<div id="container">
<div id="TreeGrid"></div>
</div>
<script>
var ele = document.getElementById('container');
if(ele) {
ele.style.visibility = "visible";
}
</script>
<script src="index.js" type="text/javascript"></script>
</body></html>
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 editSettings.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.
ej.treegrid.TreeGrid.Inject(ej.treegrid.Edit, ej.treegrid.Toolbar);
var treeGridObj = new ej.treegrid.TreeGrid({
dataSource: sampleData,
childMapping: 'subtasks',
toolbar: ['Add', 'Edit', 'Delete', 'Update', 'Cancel'],
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Dialog',
template: '#dialogtemplate' },
treeColumnIndex: 1,
columns: [
{ field: 'taskID', headerText: 'Task ID', isPrimaryKey: true, width: 90, textAlign: 'Right'},
{ field: 'taskName', headerText: 'Task Name', width: 180 },
{
field: 'startDate', headerText: 'Start Date', width: 90, textAlign: 'Right', type: 'date',format: 'yMd'
},
{ field: 'progress', headerText: 'Progress', width: 80, textAlign: 'Right' }
],
height: 270,
actionBegin: function(args){
if (args.requestType === 'save') {
// cast string to integer value.
args.data['progress'] = parseFloat(args.form.querySelector("#progress").value);
}
},
actionComplete: function(args){
if ((args.requestType === 'beginEdit' || args.requestType === 'add')) {
// Add Validation Rules
args.form.ej2_instances[0].addRules('progress', {max: 100});
// EJ2-control Rendering
var priorityData = ej.data.DataUtil.distinct(treeGridObj.grid.dataSource, 'priority',true);
new ej.dropdowns.DropDownList({value: args.rowData.priority, popupHeight: '200px', floatLabelType: 'Always',
dataSource: priorityData, fields: {text: 'priority', value: 'priority'}, placeholder: 'Priority'}, args.form.elements.namedItem('priority'));
new ej.calendars.DatePicker({value: args.rowData.startDate, floatLabelType: 'Always', placeholder: 'Start Date'}, args.form.elements.namedItem('startDate'))
new ej.calendars.DatePicker({value: args.rowData.endDate, floatLabelType: 'Always', placeholder: 'End Date'}, args.form.elements.namedItem('endDate'))
new ej.buttons.CheckBox({ label: 'Approved', checked: args.rowData.approved }, args.form.elements.namedItem('approved'));
new ej.inputs.NumericTextBox({value: args.rowData.progress, format: 'n', placeholder: 'Progress', floatLabelType: 'Always' }, args.form.elements.namedItem('progress'));
// Set initail Focus
if (args.requestType === 'beginEdit') {
(args.form.elements.namedItem('taskName')).focus();
}
}
}
});
treeGridObj.appendTo('#TreeGrid');
#container {
visibility: hidden;
}
#loader {
color: #008cff;
font-family: 'Helvetica Neue','calibiri';
font-size: 14px;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
.form-group .col-md-6 {
width: 250px;
}
<!DOCTYPE html><html lang="en"><head>
<title>EJ2 Grid</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Typescript Grid Control">
<meta name="author" content="Syncfusion">
<link href="index.css" rel="stylesheet">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css">
<link href="//cdn.syncfusion.com/ej2/20.1.55/ej2-base/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/20.1.55/ej2-grids/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/20.1.55/ej2-treegrid/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/20.1.55/ej2-buttons/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/20.1.55/ej2-popups/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/20.1.55/ej2-navigations/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/20.1.55/ej2-dropdowns/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/20.1.55/ej2-lists/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/20.1.55/ej2-inputs/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/20.1.55/ej2-calendars/styles/material.css" rel="stylesheet">
<link href="//cdn.syncfusion.com/ej2/20.1.55/ej2-splitbuttons/styles/material.css" rel="stylesheet">
<script src="https://cdn.syncfusion.com/ej2/20.1.55/dist/ej2.min.js" type="text/javascript"></script>
<script src="es5-datasource.js" type="text/javascript"></script>
</head>
<body>
<div id="container">
<div id="TreeGrid"></div>
</div>
<script id="dialogtemplate" type="text/x-template">
<div>
<div class="form-row" >
<div class="form-group col-md-6">
<div class="e-float-input e-control-wrapper">
<input id="taskID" name="taskID" type="text" value=${if(isAdd)} '' ${else} ${taskID} ${/if} ${if(isAdd)}'' ${else} disabled ${/if}/>
<span class="e-float-line"></span>
<label class="e-float-text e-label-top" for="OrderID">Task ID</label>
</div>
</div>
<div class="form-group col-md-6">
<div class="e-float-input e-control-wrapper">
<input id="taskName" name="taskName" type="text" value=${if(isAdd)} '' ${else} ${taskName} ${/if} />
<span class="e-float-line"></span>
<label class="e-float-text e-label-top" for="taskName">Task Name</label>
</div>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6">
<div>
<input id="priority" name="priority" type="text" value=${if(isAdd)} '' ${else} ${priority} ${/if} />
</div>
</div>
<div class="form-group col-md-6">
<input id="progress" value=${if(isAdd)} '' ${else} ${progress} ${/if} />
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6">
<div class="e-float-input e-control-wrapper">
<input type="text" name="startDate" id="startDate" value=${if(isAdd)} '' ${else} ${startDate} ${/if} />
<span class="e-float-line"></span>
</div>
</div>
<div class="form-group col-md-6">
<div class="e-float-input e-control-wrapper">
<input type="text" name="endDate" id="endDate" value=${if(isAdd)} '' ${else} ${endDate} ${/if} />
<span class="e-float-line"></span>
</div>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6">
<input type="checkbox" name="approved" id="approved" ${if(isAdd)} '' ${else} checked ${/if} />
</div>
</div>
</div>
</script>
<script>
var ele = document.getElementById('container');
if(ele) {
ele.style.visibility = "visible";
}
</script>
<script src="index.js" type="text/javascript"></script>
</body></html>
The template form editors should have name attribute.
The Essential JS2 packages has a built-in template engine. Using the template engine, you can access the row information inside the HTML element and bind the attributes, values, or elements based on this row information.
The following properties will be available at the time of template execution.
Property Name | Usage |
---|---|
isAdd | A Boolean property; it defines whether the current row should be a new record or not. |
In the following code example, the OrderID
textbox has been disabled by using the isAdd
property.
// The disabled attributes will be added based on the isAdd property.
<input id="taskID" name="taskID" type="text" value=${if(isAdd)} '' ${else} ${taskID} ${/if} ${if(isAdd)}'' ${else} disabled ${/if}/>
The following code example illustrates rendering the taskID
textbox, when a new record is added.
${if(isAdd)}
<div class="form-group col-md-6">
<div class="e-float-input e-control-wrapper">
<input id="taskID" name="taskID" type="text" value=${if(isAdd)} '' ${else} ${taskID} ${/if} ${if(isAdd)}'' ${else} disabled ${/if}/>
<span class="e-float-line"></span>
<label class="e-float-text e-label-top" for="OrderID">Task ID</label>
</div>
</div>
${/if}
The dialog template syntax supports the ES6 expression string literals, and you can refer to the
Template Engine
for more template syntax.
You can convert the form editors to EJ2 controls in the actionComplete
event based on the requestType
as beginEdit
or add
.
The following code example illustrates rendering the drop-down list control in the actionComplete
event.
actionComplete: (args: DialogEditEventArgs) => {
if ((args.requestType === 'beginEdit' || args.requestType === 'add')) {
let priorityData: {}[] = DataUtil.distinct(treeGridObj.grid.dataSource, 'priority',true);
new DropDownList({value: args.rowData.priority, popupHeight: '200px', floatLabelType: 'Always',
dataSource: priorityData, fields: {text: 'priority', value: 'priority'}, placeholder: 'Priority'}, args.form.elements.namedItem('priority') as HTMLInputElement);
}
}
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.
actionBegin: (args: SaveEventArgs) => {
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
.
actionComplete: (args: DialogEditEventArgs) => {
// 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.
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 editSettings.newRowPosition
property. 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 tree grid.
ej.treegrid.TreeGrid.Inject(ej.treegrid.Edit, ej.treegrid.Toolbar);
var treeGridObj = new ej.treegrid.TreeGrid({
dataSource: sampleData,
childMapping: 'subtasks',
toolbar: ['Add', 'Delete', 'Update', 'Cancel'],
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, newRowPosition: 'Child', mode: 'Cell' },
treeColumnIndex: 1,
columns: [
{ field: 'taskID', headerText: 'Task ID', isPrimaryKey: true, width: 90, textAlign: 'Right'},
{ field: 'taskName', headerText: 'Task Name', width: 180 },
{
field: 'startDate', headerText: 'Start Date', width: 90, textAlign: 'Right', editType: 'datepickeredit', type: 'date', format: 'yMd'
},
{ field: 'duration', headerText: 'Duration', width: 80, textAlign: 'Right' }
],
height: 270
});
treeGridObj.appendTo('#TreeGrid');
<!DOCTYPE html><html lang="en"><head>
<title>EJ2 Tree Grid</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Typescript Tree Grid Control">
<meta name="author" content="Syncfusion">
<link href="index.css" rel="stylesheet">
<!-- Syncfusion Essential JS 2 Styles -->
<link rel="stylesheet" href="https://cdn.syncfusion.com/ej2/20.1.55/material.css">
<link href="//cdn.syncfusion.com/ej2/20.1.55/ej2-splitbuttons/styles/material.css" rel="stylesheet">
<script src="https://cdn.syncfusion.com/ej2/20.1.55/dist/ej2.min.js" type="text/javascript"></script>
<script src="es5-datasource.js" type="text/javascript"></script>
</head>
<body>
<div id="container">
<div id="TreeGrid"></div>
</div>
<script>
var ele = document.getElementById('container');
if(ele) {
ele.style.visibility = "visible";
}
</script>
<script src="index.js" type="text/javascript"></script>
</body></html>
The command column provides an option to add CRUD action buttons in a column. This can be defined by the column.commands
property.
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. |
ej.treegrid.TreeGrid.Inject(ej.treegrid.Edit, ej.treegrid.CommandColumn);
var treeGridObj = new ej.treegrid.TreeGrid({
dataSource: sampleData,
childMapping: 'subtasks',
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Row' },
treeColumnIndex: 1,
columns: [
{ field: 'taskID', headerText: 'Task ID', isPrimaryKey: true, width: 90, textAlign: 'Right'},
{ field: 'taskName', headerText: 'Task Name', width: 180 },
{ field: 'duration', headerText: 'Duration', width: 80, textAlign: 'Right' },
{
headerText: 'Manage Records', width: 130,
commands: [{ type: 'Edit', buttonOption: { iconCss: ' e-icons e-edit', cssClass: 'e-flat' } },
{ type: 'Delete', buttonOption: { iconCss: 'e-icons e-delete', cssClass: 'e-flat' } },
{ type: 'Save', buttonOption: { iconCss: 'e-icons e-update', cssClass: 'e-flat' } },
{ type: 'Cancel', buttonOption: { iconCss: 'e-icons e-cancel-icon', cssClass: 'e-flat' } }]
}
],
height: 270
});
treeGridObj.appendTo('#TreeGrid');
<!DOCTYPE html><html lang="en"><head>
<title>EJ2 Tree Grid</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Typescript Tree Grid Control">
<meta name="author" content="Syncfusion">
<link href="index.css" rel="stylesheet">
<!-- Syncfusion Essential JS 2 Styles -->
<link rel="stylesheet" href="https://cdn.syncfusion.com/ej2/20.1.55/material.css">
<link href="//cdn.syncfusion.com/ej2/20.1.55/ej2-splitbuttons/styles/material.css" rel="stylesheet">
<script src="https://cdn.syncfusion.com/ej2/20.1.55/dist/ej2.min.js" type="text/javascript"></script>
<script src="es5-datasource.js" type="text/javascript"></script>
</head>
<body>
<div id="container">
<div id="TreeGrid"></div>
</div>
<script>
var ele = document.getElementById('container');
if(ele) {
ele.style.visibility = "visible";
}
</script>
<script src="index.js" type="text/javascript"></script>
</body></html>
The custom command buttons can be added in a column by using the column.commands
property and
the action for the custom buttons can be defined in the buttonOption.click
event.
ej.treegrid.TreeGrid.Inject(ej.treegrid.Edit, ej.treegrid.CommandColumn);
var onClick = function(args){
var rowIndex = ej.base.closest(args.target, '.e-row').rowIndex;
var data = treeGridObj.getCurrentViewRecords();
alert(JSON.stringify(data[rowIndex]));
}
var treeGridObj = new ej.treegrid.TreeGrid({
dataSource: sampleData,
childMapping: 'subtasks',
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Row' },
treeColumnIndex: 1,
columns: [
{ field: 'taskID', headerText: 'Task ID', isPrimaryKey: true, width: 90, textAlign: 'Right'},
{ field: 'taskName', headerText: 'Task Name', width: 180 },
{ field: 'duration', headerText: 'Duration', width: 80, textAlign: 'Right' },
{ headerText: 'Commands', width: 120, commands: [{ buttonOption: { content: 'Details', cssClass: 'e-flat', click: onClick } }]},
],
height: 270
});
treeGridObj.appendTo('#TreeGrid');
<!DOCTYPE html><html lang="en"><head>
<title>EJ2 Tree Grid</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Typescript Tree Grid Control">
<meta name="author" content="Syncfusion">
<link href="index.css" rel="stylesheet">
<!-- Syncfusion Essential JS 2 Styles -->
<link rel="stylesheet" href="https://cdn.syncfusion.com/ej2/20.1.55/material.css">
<link href="//cdn.syncfusion.com/ej2/20.1.55/ej2-splitbuttons/styles/material.css" rel="stylesheet">
<script src="https://cdn.syncfusion.com/ej2/20.1.55/dist/ej2.min.js" type="text/javascript"></script>
<script src="es5-datasource.js" type="text/javascript"></script>
</head>
<body>
<div id="container">
<div id="TreeGrid"></div>
</div>
<script>
var ele = document.getElementById('container');
if(ele) {
ele.style.visibility = "visible";
}
</script>
<script src="index.js" type="text/javascript"></script>
</body></html>
The delete confirm dialog can be shown when deleting a record by defining the showDeleteConfirmDialog
as true
ej.treegrid.TreeGrid.Inject(ej.treegrid.Edit, ej.treegrid.Toolbar);
var treeGridObj = new ej.treegrid.TreeGrid({
dataSource: sampleData,
childMapping: 'subtasks',
toolbar: ['Add', 'Delete', 'Update', 'Cancel'],
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, showDeleteConfirmDialog: true, mode: 'Cell' },
treeColumnIndex: 1,
columns: [
{ field: 'taskID', headerText: 'Task ID', isPrimaryKey: true, width: 90, textAlign: 'Right'},
{ field: 'taskName', headerText: 'Task Name', width: 180 },
{
field: 'startDate', headerText: 'Start Date', width: 90, textAlign: 'Right', editType: 'datepickeredit', type: 'date', format: 'yMd'
},
{ field: 'duration', headerText: 'Duration', width: 80, textAlign: 'Right' }
],
height: 270
});
treeGridObj.appendTo('#TreeGrid');
<!DOCTYPE html><html lang="en"><head>
<title>EJ2 Tree Grid</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Typescript Tree Grid Control">
<meta name="author" content="Syncfusion">
<link href="index.css" rel="stylesheet">
<!-- Syncfusion Essential JS 2 Styles -->
<link rel="stylesheet" href="https://cdn.syncfusion.com/ej2/20.1.55/material.css">
<link href="//cdn.syncfusion.com/ej2/20.1.55/ej2-splitbuttons/styles/material.css" rel="stylesheet">
<script src="https://cdn.syncfusion.com/ej2/20.1.55/dist/ej2.min.js" type="text/javascript"></script>
<script src="es5-datasource.js" type="text/javascript"></script>
</head>
<body>
<div id="container">
<div id="TreeGrid"></div>
</div>
<script>
var ele = document.getElementById('container');
if(ele) {
ele.style.visibility = "visible";
}
</script>
<script src="index.js" type="text/javascript"></script>
</body></html>
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 columns.validationRules
.
ej.treegrid.TreeGrid.Inject(ej.treegrid.Edit, ej.treegrid.Toolbar);
var treeGridObj = new ej.treegrid.TreeGrid({
dataSource: sampleData,
childMapping: 'subtasks',
toolbar: ['Add', 'Delete', 'Update', 'Cancel'],
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, showDeleteConfirmDialog: true, mode: 'Cell' },
treeColumnIndex: 1,
columns: [
{
field: 'taskID', headerText: 'Task ID', isPrimaryKey: true, textAlign: 'Right',
validationRules: { required: true, number: true }, width: 100
},
{
field: 'taskName', headerText: 'Task Name', editType: 'stringedit',
validationRules: { required: true }, width: 170
},
{
field: 'startDate', headerText: 'Start Date', textAlign: 'Right', width: 180,
editType: 'datetimepickeredit', edit: { params: { format: 'M/d/y hh:mm a' } },
format: { format: 'M/d/y hh:mm a', type: 'dateTime' }, validationRules: { date: true }
},
{
field: 'approved', headerText: 'Approved', width: 110, editType: 'booleanedit',
type: 'boolean', displayAsCheckBox: true
},
{
field: 'progress', headerText: 'Progress', textAlign: 'Right', width: 120,
editType: 'numericedit', validationRules: { number: true, min: 0 }, edit: { params: { format: 'n' } }
},
{ field: 'priority', headerText: 'Priority', width: 110, editType: 'dropdownedit', validationRules: { required: true } }
],
height: 270
});
treeGridObj.appendTo('#TreeGrid');
<!DOCTYPE html><html lang="en"><head>
<title>EJ2 Tree Grid</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Typescript Tree Grid Control">
<meta name="author" content="Syncfusion">
<link href="index.css" rel="stylesheet">
<!-- Syncfusion Essential JS 2 Styles -->
<link rel="stylesheet" href="https://cdn.syncfusion.com/ej2/20.1.55/material.css">
<link href="//cdn.syncfusion.com/ej2/20.1.55/ej2-splitbuttons/styles/material.css" rel="stylesheet">
<script src="https://cdn.syncfusion.com/ej2/20.1.55/dist/ej2.min.js" type="text/javascript"></script>
<script src="es5-datasource.js" type="text/javascript"></script>
</head>
<body>
<div id="container">
<div id="TreeGrid"></div>
</div>
<script>
var ele = document.getElementById('container');
if(ele) {
ele.style.visibility = "visible";
}
</script>
<script src="index.js" type="text/javascript"></script>
</body></html>
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.
ej.treegrid.TreeGrid.Inject(ej.treegrid.Edit, ej.treegrid.Toolbar);
var customFn = function(args) {
return args['value'].length <= 8;
};
var treeGridObj = new ej.treegrid.TreeGrid({
dataSource: sampleData,
childMapping: 'subtasks',
toolbar: ['Add', 'Delete', 'Update', 'Cancel'],
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, showDeleteConfirmDialog: true, mode: 'Cell' },
treeColumnIndex: 1,
columns: [
{ field: 'taskID', headerText: 'Task ID', isPrimaryKey: true, width: 90, textAlign: 'Right'},
{ field: 'taskName', headerText: 'Task Name', width: 180 },
{
field: 'startDate', headerText: 'Start Date', width: 90, textAlign: 'Right', editType: 'datepickeredit', type: 'date', format: 'yMd'
},
{ field: 'priority', headerText: 'Priority', width: 80, validationRules: { required: true, minLength: [customFn, 'Value should be within 8 letters'] } }
],
height: 270
});
treeGridObj.appendTo('#TreeGrid');
<!DOCTYPE html><html lang="en"><head>
<title>EJ2 Tree Grid</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Typescript Tree Grid Control">
<meta name="author" content="Syncfusion">
<link href="index.css" rel="stylesheet">
<!-- Syncfusion Essential JS 2 Styles -->
<link rel="stylesheet" href="https://cdn.syncfusion.com/ej2/20.1.55/material.css">
<link href="//cdn.syncfusion.com/ej2/20.1.55/ej2-splitbuttons/styles/material.css" rel="stylesheet">
<script src="https://cdn.syncfusion.com/ej2/20.1.55/dist/ej2.min.js" type="text/javascript"></script>
<script src="es5-datasource.js" type="text/javascript"></script>
</head>
<body>
<div id="container">
<div id="TreeGrid"></div>
</div>
<script>
var ele = document.getElementById('container');
if(ele) {
ele.style.visibility = "visible";
}
</script>
<script src="index.js" type="text/javascript"></script>
</body></html>
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 treegrid, data are fetched from remote data and bound to the treegrid using url
property of DataManager
.
You can map The CRUD operation in treegrid can be mapped to server-side Controller actions using the properties insertUrl
, removeUrl
, updateUrl
and batchUrl
.
The following code example describes the above behavior.
import { TreeGrid, Edit, Toolbar } from '@syncfusion/ej2-treegrid';
import { DataManager, UrlAdaptor } from '@syncfusion/ej2-data';
TreeGrid.Inject(Edit, Toolbar);
let data: DataManager = new DataManager({
url: "Home/DataSource",
updateUrl: "Home/Update",
insertUrl: "Home/Insert",
removeUrl: "Home/Delete",
batchUrl: "Home/Remove",
adaptor: new UrlAdaptor
});
let treeGridObj: TreeGrid = new TreeGrid({
dataSource: data,
idMapping: 'TaskID',
parentIdMapping: 'parentItem',
hasChildMapping: 'isParent',
toolbar: ['Add', 'Edit', 'Delete', 'Update', 'Cancel'],
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Row', newRowPosition: 'Below' },
treeColumnIndex: 1,
columns: [
{ field: 'TaskID', headerText: 'Task ID', isPrimaryKey: true, width: 90, textAlign: 'Right'},
{ field: 'TaskName', headerText: 'Task Name', width: 180 },
{
field: 'StartDate', headerText: 'Start Date', width: 90, textAlign: 'Right', editType: 'datepickeredit', type: 'date', format: 'yMd'
},
{ field: 'Priority', headerText: 'Priority', width: 80, validationRules: { required: true } }
],
height: 270
});
treeGridObj.appendTo('#TreeGrid');
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.
public ActionResult DataSource(DataManager dm)
{
var DataSource = TreeData.GetTree();
DataOperations operation = new DataOperations();
if (dm.Where != null && dm.Where.Count > 0)
{
DataSource = operation.PerformFiltering(DataSource, dm.Where, "and"); //perform filtering and maintain child records on Expand/Collapse operation
}
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);
}
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 and also we have inserted new record based on the newRowPosition TreeGrid editSettings as “Below”.
public void Insert(TreeGridData value, int relationalKey)
{
var i = 0;
for (; i < TreeData.tree.Count; i++)
{
if (TreeData.tree[i].TaskID == relationalKey)
{
break;
}
}
i += FindChildRecords(relationalKey); // Inserted new record when newRowPosition API is in "Below".
TreeData.tree.Insert(i + 1, 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;
}
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.
public ActionResult Update(TreeGridData value)
{
var val = TreeData.tree.Where(ds => ds.TaskID == value.TaskID).FirstOrDefault();
val.TaskName = value.TaskName;
val.StartDate = value.StartDate;
val.Duration = value.Duration;
val.Priority = value.Priority;
val.Progress = value.Progress;
return Json(value);
}
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.
public ActionResult Delete(int key)
{
TreeData.tree.Remove(TreeData.tree.Where(ds => ds.TaskID == key).FirstOrDefault());
}
// Remove method (batchUrl) will be triggered when we delete parent record.
public ActionResult Remove(List<TreeGridData> changed, List<TreeGridData> added, List<TreeGridData> deleted)
{
for (var i = 0; i < deleted.Count; i++)
{
TreeData.tree.Remove(TreeData.tree.Where(ds => ds.TaskID == deleted[i].TaskID).FirstOrDefault());
}
}
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.
import { TreeGrid, Edit, Toolbar } from '@syncfusion/ej2-treegrid';
import { DataManager, RemoteSaveAdaptor } from '@syncfusion/ej2-data';
TreeGrid.Inject(Edit, Toolbar);
let dataSource: DataManager = new DataManager({
json: window.griddata,
updateUrl: "Home/Update",
insertUrl: "Home/Insert",
removeUrl: "Home/Delete",
batchUrl: "Home/Remove",
adaptor: new RemoteSaveAdaptor
});
let treeGridObj: TreeGrid = new TreeGrid({
dataSource: dataSource,
idMapping: 'TaskID',
parentIdMapping: 'parentItem',
hasChildMapping: 'isParent',
toolbar: ['Add', 'Edit', 'Delete', 'Update', 'Cancel'],
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Row' },
treeColumnIndex: 1,
columns: [
{ field: 'TaskID', headerText: 'Task ID', isPrimaryKey: true, width: 90, textAlign: 'Right'},
{ field: 'TaskName', headerText: 'Task Name', width: 180 },
{
field: 'StartDate', headerText: 'Start Date', width: 90, textAlign: 'Right', editType: 'datepickeredit', type: 'date', format: 'yMd'
},
{ field: 'Priority', headerText: 'Priority', width: 80, validationRules: { required: true } }
],
height: 270
});
treeGridObj.appendTo('#TreeGrid');
The following code example describes how to fetch the data from ViewBag
in angular.
<script type="text/javascript">
window.griddata = '@Html.Raw(Json.Encode(ViewBag.dataSource))';
</script>
The following code example describes the CRUD operations handled at server-side.
public ActionResult Index(DataManager dm)
{
var data = TreeData.GetTree();
ViewBag.dataSource = data;
return View();
}
public void Insert(TreeData value, int relationalKey)
{
var i = 0;
for (; i < TreeData.tree.Count; i++)
{
if (TreeData.tree[i].TaskID == relationalKey)
{
break;
}
}
i += FindChildRecords(relationalKey); // Inserted new record when newRowPosition API is in "Below".
TreeData.tree.Insert(i + 1, value);
}
public ActionResult Update(TreeData value)
{
var val = TreeData.tree.Where(ds => ds.TaskID == value.TaskID).FirstOrDefault();
val.TaskName = value.TaskName;
val.StartDate = value.StartDate;
val.Duration = value.Duration;
val.Priority = value.Priority;
val.Progress = value.Progress;
return Json(value);
}
public ActionResult Delete(int key)
{
TreeData.tree.Remove(TreeData.tree.Where(ds => ds.TaskID == key).FirstOrDefault());;
}
// Remove method (batchUrl) will be triggered when we delete parent record.
public ActionResult Remove(List<TreeGridData> changed, List<TreeGridData> added, List<TreeGridData> deleted)
{
for (var i = 0; i < deleted.Count; i++)
{
TreeData.tree.Remove(TreeData.tree.Where(ds => ds.TaskID == deleted[i].TaskID).FirstOrDefault());
}
}
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 columns.defaultValue
.
ej.treegrid.TreeGrid.Inject(ej.treegrid.Edit, ej.treegrid.Toolbar);
var treeGridObj = new ej.treegrid.TreeGrid({
dataSource: sampleData,
childMapping: 'subtasks',
toolbar: ['Add', 'Delete', 'Update', 'Cancel'],
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, showDeleteConfirmDialog: true, mode: 'Cell' },
treeColumnIndex: 1,
columns: [
{ field: 'taskID', headerText: 'Task ID', isPrimaryKey: true, width: 90, textAlign: 'Right'},
{ field: 'taskName', headerText: 'Task Name', width: 180 },
{
field: 'startDate', headerText: 'Start Date', width: 90, textAlign: 'Right', editType: 'datepickeredit', type: 'date', format: 'yMd'
},
{ field: 'priority', headerText: 'Priority', width: 80, defaultValue: 'Normal' }
],
height: 270
});
treeGridObj.appendTo('#TreeGrid');
<!DOCTYPE html><html lang="en"><head>
<title>EJ2 Tree Grid</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Typescript Tree Grid Control">
<meta name="author" content="Syncfusion">
<link href="index.css" rel="stylesheet">
<!-- Syncfusion Essential JS 2 Styles -->
<link rel="stylesheet" href="https://cdn.syncfusion.com/ej2/20.1.55/material.css">
<link href="//cdn.syncfusion.com/ej2/20.1.55/ej2-splitbuttons/styles/material.css" rel="stylesheet">
<script src="https://cdn.syncfusion.com/ej2/20.1.55/dist/ej2.min.js" type="text/javascript"></script>
<script src="es5-datasource.js" type="text/javascript"></script>
</head>
<body>
<div id="container">
<div id="TreeGrid"></div>
</div>
<script>
var ele = document.getElementById('container');
if(ele) {
ele.style.visibility = "visible";
}
</script>
<script src="index.js" type="text/javascript"></script>
</body></html>
You can disable editing for particular columns by using the columns.allowEditing
.
In the following demo, editing is disabled for the Start Date
column.
ej.treegrid.TreeGrid.Inject(ej.treegrid.Edit, ej.treegrid.Toolbar);
var treeGridObj = new ej.treegrid.TreeGrid({
dataSource: sampleData,
childMapping: 'subtasks',
toolbar: ['Add', 'Delete', 'Update', 'Cancel'],
editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Cell' },
treeColumnIndex: 1,
columns: [
{ field: 'taskID', headerText: 'Task ID', isPrimaryKey: true, width: 90, textAlign: 'Right'},
{ field: 'taskName', headerText: 'Task Name', width: 180 },
{
field: 'startDate', headerText: 'Start Date', width: 90, allowEditing: false, textAlign: 'Right', type: 'date', format: 'yMd'
},
{ field: 'duration', headerText: 'Duration', width: 80, textAlign: 'Right' }
],
height: 270
});
treeGridObj.appendTo('#TreeGrid');
<!DOCTYPE html><html lang="en"><head>
<title>EJ2 Tree Grid</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Typescript Tree Grid Control">
<meta name="author" content="Syncfusion">
<link href="index.css" rel="stylesheet">
<!-- Syncfusion Essential JS 2 Styles -->
<link rel="stylesheet" href="https://cdn.syncfusion.com/ej2/20.1.55/material.css">
<link href="//cdn.syncfusion.com/ej2/20.1.55/ej2-splitbuttons/styles/material.css" rel="stylesheet">
<script src="https://cdn.syncfusion.com/ej2/20.1.55/dist/ej2.min.js" type="text/javascript"></script>
<script src="es5-datasource.js" type="text/javascript"></script>
</head>
<body>
<div id="container">
<div id="TreeGrid"></div>
</div>
<script>
var ele = document.getElementById('container');
if(ele) {
ele.style.visibility = "visible";
}
</script>
<script src="index.js" type="text/javascript"></script>
</body></html>
The Editing functionalities can be performed based upon the primary key value of the selected row.
If primaryKey
is not defined in the treegrid, then edit or delete action take places the first row.
You can refer to our
JavaScript Tree Grid
feature tour page for its groundbreaking feature representations. You can also explore our JavaScript Tree Grid exampleJavaScript Tree Grid example
to knows how to present and manipulate data.