How to validate node text on rename in React
You can validate the tree node text while editing using the nodeEditing event of the React Tree View (cancel the edit by setting args.cancel = true inside the event). The nodeEdited event fires after a successful rename and can also be used to react to the new value. Following is an example that shows how to validate and prevent empty values in tree node.
import * as ReactDOM from 'react-dom';
import * as React from 'react';
import { TreeViewComponent } from '@syncfusion/ej2-react-navigations';
import { enableRipple } from '@syncfusion/ej2-base';
enableRipple(true);
function App() {
let treeObj;
// Hierarchical data source for TreeView component
let hierarchicalData = [
{ id: '01', name: 'Local Disk (C:)', expanded: true,
subChild: [
{
id: '01-01', name: 'Program Files',
subChild: [
{ id: '01-01-01', name: 'Windows NT' },
{ id: '01-01-02', name: 'Windows Mail' },
{ id: '01-01-03', name: 'Windows Photo Viewer' },
]
},
{
id: '01-02', name: 'Users', expanded: true,
subChild: [
{ id: '01-02-01', name: 'Smith' },
{ id: '01-02-02', name: 'Public' },
{ id: '01-02-03', name: 'Admin' },
]
},
{
id: '01-03', name: 'Windows',
subChild: [
{ id: '01-03-01', name: 'Boot' },
{ id: '01-03-02', name: 'FileManager' },
{ id: '01-03-03', name: 'System32' },
]
},
]
},
{
id: '02', name: 'Local Disk (D:)',
subChild: [
{
id: '02-01', name: 'Personals',
subChild: [
{ id: '02-01-01', name: 'My photo.png' },
{ id: '02-01-02', name: 'Rental document.docx' },
{ id: '02-01-03', name: 'Pay slip.pdf' },
]
},
{
id: '02-02', name: 'Projects',
subChild: [
{ id: '02-02-01', name: 'ASP Application' },
{ id: '02-02-02', name: 'TypeScript Application' },
{ id: '02-02-03', name: 'React Application' },
]
},
{
id: '02-03', name: 'Office',
subChild: [
{ id: '02-03-01', name: 'Work details.docx' },
{ id: '02-03-02', name: 'Weekly report.docx' },
{ id: '02-03-03', name: 'Wish list.csv' },
]
},
]
},
{
id: '03', name: 'Local Disk (E:)', icon: 'folder',
subChild: [
{
id: '03-01', name: 'Pictures',
subChild: [
{ id: '03-01-01', name: 'Wind.jpg' },
{ id: '03-01-02', name: 'Stone.jpg' },
{ id: '03-01-03', name: 'Home.jpg' },
]
},
{
id: '03-02', name: 'Documents',
subChild: [
{ id: '03-02-01', name: 'Environment Pollution.docx' },
{ id: '03-02-02', name: 'Global Warming.ppt' },
{ id: '03-02-03', name: 'Social Network.pdf' },
]
},
{
id: '03-03', name: 'Study tailwind3s',
subChild: [
{ id: '03-03-01', name: 'UI-Guide.pdf' },
{ id: '03-03-02', name: 'Tutorials.zip' },
{ id: '03-03-03', name: 'TypeScript.7z' },
]
},
]
}
];
let fields = { dataSource: hierarchicalData, id: 'id', text: 'name', child: 'subChild' };
let allowEditing = true;
function onNodeEdited(args) {
let displayContent = "";
if (args.newText.trim() == "") {
args.cancel = true;
displayContent = "TreeView item text should not be empty";
}
else if (args.newText != args.oldText) {
displayContent = "TreeView item text edited successfully";
}
else {
displayContent = "";
}
document.getElementById("display").innerHTML = displayContent;
}
return (<div className='control-pane'>
<div className='control-section'>
<div className='control_wrapper'>
{/* Render TreeView */}
<TreeViewComponent fields={fields} allowEditing={allowEditing} ref={(tree) => { treeObj = tree; }} nodeEdited={onNodeEdited.bind(this)}/>
</div>
<div id="display"></div>
</div>
</div>);
}
export default App;
ReactDOM.render(<App />, document.getElementById('sample'));import * as ReactDOM from 'react-dom';
import * as React from 'react';
import {TreeViewComponent, NodeEditEventArgs} from '@syncfusion/ej2-react-navigations';
import {enableRipple} from '@syncfusion/ej2-base';
enableRipple(true);
function App() {
let treeObj: TreeViewComponent;
// Hierarchical data source for TreeView component
let hierarchicalData: { [key: string]: Object }[] = [
{ id: '01', name: 'Local Disk (C:)', expanded: true,
subChild: [
{
id: '01-01', name: 'Program Files',
subChild: [
{ id: '01-01-01', name: 'Windows NT' },
{ id: '01-01-02', name: 'Windows Mail' },
{ id: '01-01-03', name: 'Windows Photo Viewer' },
]
},
{
id: '01-02', name: 'Users', expanded: true,
subChild: [
{ id: '01-02-01', name: 'Smith' },
{ id: '01-02-02', name: 'Public' },
{ id: '01-02-03', name: 'Admin' },
]
},
{
id: '01-03', name: 'Windows',
subChild: [
{ id: '01-03-01', name: 'Boot' },
{ id: '01-03-02', name: 'FileManager' },
{ id: '01-03-03', name: 'System32' },
]
},
]
},
{
id: '02', name: 'Local Disk (D:)',
subChild: [
{
id: '02-01', name: 'Personals',
subChild: [
{ id: '02-01-01', name: 'My photo.png' },
{ id: '02-01-02', name: 'Rental document.docx' },
{ id: '02-01-03', name: 'Pay slip.pdf' },
]
},
{
id: '02-02', name: 'Projects',
subChild: [
{ id: '02-02-01', name: 'ASP Application' },
{ id: '02-02-02', name: 'TypeScript Application' },
{ id: '02-02-03', name: 'React Application' },
]
},
{
id: '02-03', name: 'Office',
subChild: [
{ id: '02-03-01', name: 'Work details.docx' },
{ id: '02-03-02', name: 'Weekly report.docx' },
{ id: '02-03-03', name: 'Wish list.csv' },
]
},
]
},
{
id: '03', name: 'Local Disk (E:)', icon: 'folder',
subChild: [
{
id: '03-01', name: 'Pictures',
subChild: [
{ id: '03-01-01', name: 'Wind.jpg' },
{ id: '03-01-02', name: 'Stone.jpg' },
{ id: '03-01-03', name: 'Home.jpg' },
]
},
{
id: '03-02', name: 'Documents',
subChild: [
{ id: '03-02-01', name: 'Environment Pollution.docx' },
{ id: '03-02-02', name: 'Global Warming.ppt' },
{ id: '03-02-03', name: 'Social Network.pdf' },
]
},
{
id: '03-03', name: 'Study tailwind3s',
subChild: [
{ id: '03-03-01', name: 'UI-Guide.pdf' },
{ id: '03-03-02', name: 'Tutorials.zip' },
{ id: '03-03-03', name: 'TypeScript.7z' },
]
},
]
}
];
let fields: object = { dataSource: hierarchicalData, id: 'id', text: 'name', child: 'subChild' };
let allowEditing:boolean = true;
function onNodeEdited(args: NodeEditEventArgs) {
let displayContent:string = "";
if (args.newText.trim() == "") {
args.cancel=true;
displayContent = "TreeView item text should not be empty";
}
else if (args.newText != args.oldText) {
displayContent = "TreeView item text edited successfully";
} else {
displayContent = "";
}
document.getElementById("display").innerHTML = displayContent;
}
return (
<div className = 'control-pane'>
<div className='control-section'>
<div className='control_wrapper'>
{/* Render TreeView */}
<TreeViewComponent fields={fields} allowEditing={allowEditing} ref={(tree) => { treeObj = tree}} nodeEdited={onNodeEdited.bind(this)} />
</div>
<div id="display"></div>
</div>
</div>
)
}
export default App;
ReactDOM.render(<App />, document.getElementById('sample'));<!DOCTYPE html>
<html lang="en">
<head>
<title>Syncfusion React TreeView</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Essential JS 2 for React Components" />
<meta name="author" content="Syncfusion" />
<link href="style.css" rel="stylesheet"/>
<link href="https://cdn.syncfusion.com/ej2/35.1.37/ej2-base/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/35.1.37/ej2-inputs/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/35.1.37/ej2-react-navigations/styles/tailwind3.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
</head>
<body>
<div id='treeparent'>
<div id='sample'>
<div id='loader'>Loading....</div>
</div>
</div>
</body>
</html>#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
#treeparent {
display: block;
max-width: 350px;
max-height: 350px;
margin: auto;
overflow: auto;
border: 1px solid #dddddd;
border-radius: 3px;
}
#display {
max-width: 500px;
margin: auto;
padding: 10px;
}