sorry but I dont understand well refs. I've been reading react doc but I dont know how create an array of refs and access a node when check item.
My idea is ref all Tree Nodes and when call onCheck access to current ref and change property checked to a different status to current item, his parent items and his child items using javascript using childNodes, parentNode, nextSibling and previousSibling.
onCheck = (checkedKeys, event) => {
how can get node checked??? it always returns last node
const node = this.myRef.current;
console.log(node)
}
componentDidMount() {
// I have to do something here???
}
render() {
const loop = (data) => {
return data.map((item) => {
if (item.children && item.children.length) {
return <TreeNode ref={this.myRef} title={item.name} key={item.key} checked={item.checked} >{loop(item.children)}</TreeNode>;
}
return (
<TreeNode ref={this.myRef} title={item.name} key={item.key} isLeaf={item.isLeaf} checked={item.checked} />
);
});
};
return (
<div className="draggable-container">
<Tree
// Expand
expandedKeys={this.state.expandedKeys}
onExpand={this.onExpand} autoExpandParent={this.state.autoExpandParent}
// Draggable
draggable
onDragStart={this.onDragStart}
onDragEnter={this.onDragEnter}
onDrop={this.onDrop}
// Select && Check
onSelect={this.onSelect}
checkable onCheck={this.onCheck} checkedKeys={this.state.checkedKeys} >
{ loop(this.state.treeData) }
</Tree>
</div>
);
}
Instead of using React.createRef, you can make use of ref callback like
constructor(props) {
super(props);
this.myRef = {};
}
onCheck = (checkedKeys, event) => {
how can get node checked??? it always returns last node
const checkedKey = // get the checkedKey here, if its a array, loop and use
const node = this.myRef[checkedKey];
console.log(node)
}
render() {
const loop = (data) => {
return data.map((item, index) => {
if (item.children && item.children.length) {
return <TreeNode ref={(ref) => this.myRef[key] = ref} title={item.name} key={item.key} checked={item.checked} >{loop(item.children)}</TreeNode>;
}
return (
<TreeNode ref={(ref) => this.myRef[key] = ref} title={item.name} key={item.key} isLeaf={item.isLeaf} checked={item.checked} />
);
});
};
return (
<div className="draggable-container">
<Tree
// Expand
expandedKeys={this.state.expandedKeys}
onExpand={this.onExpand} autoExpandParent={this.state.autoExpandParent}
// Draggable
draggable
onDragStart={this.onDragStart}
onDragEnter={this.onDragEnter}
onDrop={this.onDrop}
// Select && Check
onSelect={this.onSelect}
checkable onCheck={this.onCheck} checkedKeys={this.state.checkedKeys} >
{ loop(this.state.treeData) }
</Tree>
</div>
);
}
This is my solution, because I had to modify treeData:
onCheck = (checkedKeys, event) => {
// console.log(this.treeData);
const checkedKey = event.node.props.eventKey;
this.updateItemChecked(checkedKey);
this.setState({ checkedKeys: checkedKeys }, () => {
this.props.parentTree(this.treeData);
});
}
updateItemChecked = (key) => {
var result = getNodeByKey(key, this.treeData);
if (result.type.localeCompare('folder') !== 0) {
if (result.checked === true ) {
result.checked = false;
} else {
result.checked = true;
}
} else {
this.checkIfFolderHasItem(result);
}
}
checkIfFolderHasItem = (result) => {
if ( result.children && result.children.length > 0) {
result.children.forEach( (item) => {
if (item.type.localeCompare('folder') !== 0) {
this.updateItemChecked(item.key);
} else {
this.checkIfFolderHasItem(item);
}
});
}
}
// Expand
onExpand = (expandedKeys, event) => {
// console.log('onExpand', expandedKeys);
const checkedKey = event.node.props.eventKey;
this.updateFolderExpanded(checkedKey);
this.setState({ expandedKeys, autoExpandParent: false }, ()=> {
this.props.parentTree(this.treeData);
});
}
updateFolderExpanded = (key) => {
var result = getNodeByKey(key, this.treeData);
if (result.type.localeCompare('folder') === 0) {
if (result.expanded === true ) {
result.expanded = false;
} else {
result.expanded = true;
}
}
}
render() {
const loop = (data) => {
return data.map((item) => {
if (item.children && item.children.length) {
return <TreeNode title={item.name} key={item.key} checked={item.checked} >{loop(item.children)}</TreeNode>;
}
return (
<TreeNode title={item.name} key={item.key} isLeaf={item.isLeaf} checked={item.checked} />
);
});
};
return (
<div className="draggable-container">
{
// (this.state.showModal) ? <TreeModal show={this.state.showModal} info={this.state.selected} treeData={this.state.treeData} parentTreeModal={this.doParentTreeModal} /> : null
}
<Tree
// Expand
expandedKeys={this.state.expandedKeys}
onExpand={this.onExpand} autoExpandParent={this.state.autoExpandParent}
// Draggable
draggable
onDragStart={this.onDragStart}
onDragEnter={this.onDragEnter}
onDrop={this.onDrop}
// Select && Check
onSelect={this.onSelect}
checkable onCheck={this.onCheck} checkedKeys={this.state.checkedKeys} >
{ loop(this.state.treeData) }
</Tree>
</div>
);
}
JSON Example:
[
{
"name": "Capas1",
"key": "0-23",
"isLeaf": false,
"type": "folder",
"expanded": true,
"children": [{
"name": "sectores",
"key": "0-20",
"isLeaf": true,
"type": "layer",
"checked": true
},
{
"name": "distribucion",
"key": "0-22",
"isLeaf": true,
"type": "layer",
"checked": false
}]
},
{
"name": "Nueva Carpeta0",
"key": "0-624",
"isLeaf": false,
"type": "folder",
"expanded": false,
"checked": false
},
{
"name": "Nueva Carpeta1",
"key": "0-625",
"isLeaf": false,
"type": "folder",
"expanded": true,
"children": [{
"name": "Nueva Carpeta2",
"key": "0-629",
"isLeaf": false,
"type": "folder",
"expanded": true,
"children": [{
"name": "Nueva Carpeta3",
"key": "0-623",
"isLeaf": false,
"type": "folder",
"expanded": true,
"children": [{
"name": "distribucion33",
"key": "0-99",
"isLeaf": true,
"type": "layer",
"checked": true
}]
}]
}]
},
{
"name": "sectores1",
"key": "0-27",
"isLeaf": true,
"type": "layer",
"checked": true
},
{
"name": "sectores12",
"key": "0-89",
"isLeaf": true,
"type": "layer",
"checked": false
},
{
"name": "Capas 2",
"key": "0-588",
"isLeaf": false,
"type": "folder",
"expanded": false,
"children": [{
"name": "Capas 3",
"key": "0-589",
"isLeaf": false,
"type": "folder",
"expanded": false,
"children": [{
"name": "Prueba",
"key": "0-36",
"isLeaf": true,
"type": "layer",
"checked": false
}]
}]
}
]
Related
I am fetching questions using an API and displaying question with dynamic radio options like this
[
{
"id": "question01",
"question": "Which of the following profiles you belongs",
"multiple": false,
"options": [
{
"id": "option01",
"title": "Buyer"
},
{
"id": "option02",
"title": "Planner"
},
{
"id": "option03",
"title": "Merchandiser"
},
{
"id": "option04",
"title": "Designer"
},
{
"id": "option05",
"title": "Analyst"
}
]
},
{
"id": "question02",
"question": "Which of the following is your responsibility?",
"multiple": true,
"options": [
{
"id": "option02_1",
"title": "Planning"
},
{
"id": "option02_2",
"title": "Design"
},
{
"id": "option02_3",
"title": "Development"
},
{
"id": "option02_4",
"title": "Testing"
}
]
},
{
"id": "question03",
"question": "What’s your level of seniority in the organization?",
"multiple": false,
"options": [
{
"id": "option03_1",
"title": "Entry Level"
},
{
"id": "option03_2",
"title": "Mid Level"
},
{
"id": "option03_3",
"title": "Senior Level"
}
]
},
{
"id": "question04",
"question": "Do you work with charts and dashboards to make data-backed decisions? ",
"multiple": false,
"options": [
{
"id": "option04_1",
"title": "Yes"
},
{
"id": "option04_2",
"title": "No"
},
{
"id": "option04_3",
"title": "Others"
}
]
}
]
I am rendering questions with options like this
<div>
{
questions && questions.length > 0 &&
questions.map((question, index) => {
return (
<div key={question.id}>
<div className='row'>
<div className='col-1'>
<h2 className='questionTitle'>Q{index + 1}.</h2>
</div>
<div className='col-11 questionContainer'>
<h2 className='questionTitle'>{question.question}</h2>
</div>
</div>
</div>
<div className='optionsList'>
{
question.options && question.options.map((option, index) => {
return (
<div key={option.id} className="mb-3">
<div className='d-flex align-items-center'>
{
question.multiple ?
<div className="form-check">
<input className="form-check-input form-checkbox" type="checkbox" value={option.title} onChange={() => handleAnswerSelection(option, question.id, true)} id={option.id} />
<label className="form-check-label" htmlFor={option.id}>
{option.title}
</label>
</div>
:
<div className="form-check">
<input className="form-check-input"
type="radio"
name={question.id}
value={option.title}
onChange={() => handleAnswerSelection(option,question.id, false)}
id={option.id}
checked={answersList.length && answersList.filter(ans => ans.id === question.id) && answersList.filter(ans => ans.id === question.id)[0].values[0].title === option.title }
/>
<label className="form-check-label" htmlFor={option.id}>
{option.title}
</label>
</div>
}
</div>
</div>
)
})
}
</div>
and onChange i am handling selection like this
const handleAnswerSelection = (selectedOption, ques, hasMany) => {
if (hasMany) {
//
}
else {
const answer = {
"id": ques,
"values": [selectedOption]
}
if (answersList.length > 0 && answersList.find(ans => ans.id === ques)) {
const index = answersList.findIndex(answer => answer.id === ques);
if (index > -1) {
answersList[index].values = [selectedOption];
}
}
else {
setAnswersList([...answersList, answer]);
}
}
console.log(answersList);
}
but the problem is on changing option is not reflecting at the same time also radio button is not changing.
state variables are
const [answersList, setAnswersList] = useState([]);
please help what i am doing wrong what is the solution for this ? Thanks in advance
const handleAnswerSelection = (selectedOption, ques, hasMany) => {
if (hasMany) {
//
}
else {
const answer = {
"id": ques,
"values": [selectedOption]
}
if (answersList.length > 0 && answersList.find(ans => ans.id === ques)) {
const index = answersList.findIndex(answer => answer.id === ques);
if (index > -1) {
let newAnswersList = [...answersList];
newAnswersList[index].values = [selectedOption];
setAnswersList(newAnswersList);
}
}
else {
setAnswersList([...answersList, answer]);
}
}
console.log(answersList);
}
It will be worked.
You should update answersList value using setAnswersList function.
On the following statement, the answersList value is not changed.
answersList[index].values = [selectedOption];
I'm using React Navigation to send the array additional in the DisplayItem screen, I use componentDidMount to set the state with the array and I use SectionList to display the array, the goal is to use the function pressOptional to update the value selected in the array, It works at the moment, but the problem is that it doesn't update the state in real-time, the changes in SectionList happen only when I re-render the screen.
Array: additional
Array [
Object {
"data": Array [
Object {
"id": 0,
"price": 1,
"selected": true,
"title": "Ranch",
"type": "Sides",
},
Object {
"id": 1,
"price": 1,
"selected": false,
"title": "Blue Cheese",
"type": "Sides",
},
],
"id": 0,
"required": false,
"title": "Sides",
},
Object {
"data": Array [
Object {
"id": 0,
"price": 0,
"selected": false,
"title": "Hot Sauce",
"type": "Sauces",
},
Object {
"id": 1,
"price": 0,
"selected": false,
"title": "Medium Sauce",
"type": "Sauces",
},
],
"id": 1,
"required": true,
"title": "Sauces",
},
]
Screen
class DisplayItem extends Component {
constructor(props) {
super(props);
this.state = {
additional: [],
}
}
componentDidMount() {
const { item } = this.props.route.params;
const additional = item.additional;
if (additional !== undefined) {
this.setState({additional:[...additional]})
}
}
pressOptional = (e) => {
const additional = this.state.additional;
additional.map((item) => {
if (item.title == e.type) {
item.data.map((item) => {
if (item.id == e.id) {
item.selected = !e.selected
}
})
}
})
}
render() {
const { additional } = this.state;
return (
<View>
<SectionList
sections={additional}
keyExtractor={(item, index) => item + index}
renderSectionHeader={({ section: { type, required } }) => (
<View>
<Text>{type}</Text>
</View>
)}
renderItem={({ item, section: { required } }) => {
return (
<TouchableOpacity key={item.id} onPress={() => this.pressOptional(item)}>
<Ionicons
name={item.selected == false ? 'square-outline' : 'square'}
/>
<Text>{item.title}</Text>
<Text>${item.price}</Text>
</TouchableOpacity>
)
}
}
/>
</View>
)
}};
export default DisplayItem;
Try to use useState instead State classes:
https://reactnative.dev/docs/state
I am unable to setState in handleClick function for this App.
App is working very simple, it has a data that has an entry point in forest from there it just goes thru props till it gets to Tree component where divides to Children and Datum there it has a Collapsible that takes care of the expanding logic.
Now,
I just want to mutate state I have done many copies of that state with JSON.parse(JSON.Stringify())) used Lodash for deep copy, everything works expect that copied and mutated state just doesn't want to set into setState so I can't get it to circular working.
I just want to have a unidirectional data flow, but the 'setState' just doesn't work.
The function that mutates the state mutateState takes as arguments a forest a node.id a patch or get as a string value. I have tested it million times and it works, this function mutates the state via recursion. One thing maybe it has a problem that it doesn't return anything, even if it doesn't return it still doesn't want to set that 'setState'.
I have also used debugger million times and didn't find any clue. Please I need some help.
thank you.
import "./App.css";
import { useState, useEffect, useContext, createContext } from "react";
import React from "react";
import data from "./data.json";
import _ from "lodash";
function App() {
const [state, setState] = useState(data.data);
function mutateState(forest, nodeId, getOrPatch) {
let result;
forest.forEach(function (tree) {
if (tree.id === nodeId && getOrPatch === "patch") {
tree.toggle === true ? (tree.toggle = false) : (tree.toggle = true);
} else if (tree.id === nodeId && getOrPatch === "get") {
return (result = tree.toggle);
}
helper(tree);
});
function helper(tree) {
if (tree.children !== null) {
tree.children.forEach(function (tree) {
if (tree.id === nodeId && getOrPatch === "patch") {
tree.toggle === true ? (tree.toggle = false) : (tree.toggle = true);
} else if (tree.id === nodeId && getOrPatch === "get") {
return (result = tree.toggle);
}
helper(tree);
});
}
}
return result;
}
function Forest({ root }) {
return root.map((tree) => <Tree root={tree} key={tree.id} />);
}
function Tree({ root }) {
if (root.children !== null) {
return <Children key={root.id} node={root} />;
} else {
return <Datum key={root.id} node={root} />;
}
}
function Collapsible(props) {
return (
<ul>
<button onClick={props.handleClick} className="btn">
<li>{props.datum}</li>
</button>
{props.isExpanded ? props.children : ""}
</ul>
);
}
function Children({ node }) {
const [isExpanded, setIsExpanded] = useState(false);
let stateCopy = _.cloneDeep(state)
function handleClick() {
mutateState(stateCopy, node.id,'patch')
setState(stateCopy)
isExpanded ? setIsExpanded(false) : setIsExpanded(true);
}
return (
<Collapsible
datum={node.datum}
handleClick={handleClick}
isExpanded={isExpanded}
>
{node.children.map((tree) => (
<Tree key={tree.id} root={tree} />
))}
</Collapsible>
);
}
function Datum({ node }) {
return <li>{node.datum}</li>;
}
return (
<div className="App">
<header className="App-header">
<Forest root={state} />
</header>
</div>
);
}
export default App;
data JSON
{
"data": [
{
"datum": "String",
"id": 1,
"toggle": false,
"children": [
{
"datum": "String",
"id": 2,
"toggle": false,
"children": [
{
"datum": "String",
"id": 3,
"toggle": false,
"children": []
}
]
},
{
"datum": "String",
"id": 4,
"toggle": false,
"children": []
}
]
},
{
"datum": "String",
"id": 5,
"toggle": false,
"children": [{
"datum": "String",
"id": 6,
"children": []
}]
},
{
"datum": "String",
"id": 7,
"toggle": false,
"children": [
{
"datum": "String",
"id": 8,
"toggle": false,
"children": [
{
"datum": "String",
"id": 9,
"toggle": false,
"children": [
{
"datum": "String",
"id": 10,
"toggle": false,
"children": [
{
"datum": "String",
"id": 11,
"toggle": false,
"children": []
}
]
}
]
},
{
"datum": "String",
"id": 12,
"toggle": false,
"children": [
{
"datum": "String",
"id": 13,
"toggle": false,
"children": []
}
]
}
]
},
{
"datum": "String",
"id": 14,
"toggle": false,
"children": []
}
]
}
]
}
Following code works fine the first time, It finds the correct item and changes its checked value, but if I call the same function with the same id again it returns undefined. any idea why?
This code is using in a React Native Application where the checkbox is updated using this method
CheckBox :
<CheckBox value={item.checked} key={item.id} onValueChange={setSelection} onChange={()=> {
handleChange(item.id);
}}
style={styles.checkbox}
tintColors={{ true: "#ffc324", false: "#ffc324" }}
/>
const handleChange = (id) => {
const ids = id;
let changedCheckbox = categories.find((category) => {
return category.subcategory.find((item) => {
if (item.id === ids) {
return (item.checked = !item.checked);
}
});
});
console.log(changedCheckbox);
};
This is the JSON I use
[
{
"id": 1,
"name": "MOTs",
"filename": "1610270182.png",
"bg_filename": null,
"content": "You can try this set a state like this and check if your component mounted or not. This way you are sure that if your component is unmounted you are not trying to fetch something.",
"featured": 1,
"created_at": "2021-01-10T09:16:22.000000Z",
"updated_at": "2021-01-10T09:40:37.000000Z",
"subcategory": [
{
"id": 1,
"name": "MOT1",
"category_id": 1,
"image_name": null,
"created_at": null,
"updated_at": null,
"checked": false
},
{
"id": 2,
"name": "MOT2",
"category_id": 1,
"image_name": null,
"created_at": null,
"updated_at": null,
"checked": false
},
{
"id": 3,
"name": "MOT3",
"category_id": 1,
"image_name": "1611678308.png",
"created_at": "2021-01-26T16:25:11.000000Z",
"updated_at": "2021-01-26T16:31:24.000000Z",
"checked": false
}
]
}
]
const handleChange = (id) => {
const category = categories.find(category => {
const item = category.subcategory.find(item => item.id === id);
if (item) item.checked = ! item.checked;
return !!item;
});
console.log(category)
};
Toggle checked then return boolean not checked.
change this statement
return (item.checked = !item.checked);
what you are doing when it is false it will return true, the next time its value is true so it will return false
do this instead
if (item.id===ids){
item.checked = !item.checked;
return true;
}
I'm using rc-tree, a version of tree.js to react, I dont know how create a method that when check on a tree item change a property of that element, parent items and their children items.
For example:
If I click on New Folder1 change checked value on New Folder1 item,
new Folder2, new Folder3 and finally, layer12.
If I click on layer12 change checked value on layer12, New Folder3,
New Folder2 and finally New Folder1.
And If I click on new Folder2 change checked value on Folder2,
Folder1, Folder3 and finally layer12.
Here is a json schema:
{
"name": "New Folder1",
"key": "0-625",
"isLeaf": false,
"type": "folder",
"expanded": false,
"checked": true,
"children": [{
"name": "New Folder2",
"key": "0-629",
"isLeaf": false,
"type": "folder",
"expanded": false,
"checked": true,
"children": [{
"name": "New Folder3",
"key": "0-623",
"isLeaf": false,
"type": "folder",
"expanded": false,
"checked": true,
"children": [{
"name": "layer12",
"key": "0-99",
"isLeaf": true,
"type": "layer",
"checked": true
}]
}]
}]
},
I found this method where find node when you check and item on tree. But how to change their children nodes and parent nodes.
function getNodeByKey(key, node){
var reduce = [].reduce;
function runner(result, node){
if(result || !node) return result;
return node.key === key && node || //is this the proper node?
runner(null, node.children) || //process this nodes children
reduce.call(Object(node), runner, result); //maybe this is some ArrayLike Structure
}
return runner(null, node);
}
EDIT:
In React you need to use the ref property in order to access the node element and then you can access the child and parent using javascript: reactjs
To access child and parent I guess that I have to use childNodes, parentNode, nextSibling and previousSibling.
But how can use ref property??? Because its an array of nodes
render() {
const loop = (data) => {
return data.map((item) => {
if (item.children && item.children.length) {
return <TreeNode ref={this.myRef} title={item.name} key={item.key} checked={item.checked} >{loop(item.children)}</TreeNode>;
}
return (
<TreeNode ref={this.myRef} title={item.name} key={item.key} isLeaf={item.isLeaf} checked={item.checked} />
);
});
};
return (
<div className="draggable-container">
<Tree
// Expand
expandedKeys={this.state.expandedKeys}
onExpand={this.onExpand} autoExpandParent={this.state.autoExpandParent}
// Draggable
draggable
onDragStart={this.onDragStart}
onDragEnter={this.onDragEnter}
onDrop={this.onDrop}
// Select && Check
onSelect={this.onSelect}
checkable onCheck={this.onCheck} checkedKeys={this.state.checkedKeys} >
{ loop(this.state.treeData) }
</Tree>
</div>
);
}
onCheck = (checkedKeys, event) => {
how can get node checked??? it always returns last node
const node = this.myRef.current;
console.log(node)
}
So... regarding your 'ref' issue: you assigned them all to the same variable, you should generate ref-variable for each node:
this.myRefs = {};
<TreeNode ref={itemRef=>this.myRefs[item.key]=itemRef} title={item.name} key={item.key} checked={item.checked} >{loop(item.children)}</TreeNode>
So you can access each node by its key.
Another way to implement it would be to assign a more useful keys:
{
"name": "New Folder1",
"key": "0",
"isLeaf": false,
"type": "folder",
"expanded": false,
"checked": true,
"children": [{
"name": "New Folder2",
"key": "0.0",
"isLeaf": false,
"type": "folder",
"expanded": false,
"checked": this.state.keysCheckedStatus['0.0'],
"children": [{
"name": "New Folder3",
"key": "0.0.0",
"isLeaf": false,
"type": "folder",
"expanded": false,
"checked": this.state.keysCheckedStatus['0.0.0'],
"children": [{
"name": "layer12",
"key": "0.0.0.0",
"isLeaf": true,
"type": "layer",
"checked": this.state.keysCheckedStatus['0.0.0.0']
},{
"name": "layer13",
"key": "0.0.0.1",
"isLeaf": true,
"type": "layer",
"checked": this.state.keysCheckedStatus['0.0.0.1']
}]
}]
}]
}
onCheck = (checkedKeys, event) => {
let keysCheckedStatus = this.state.keysCheckedStatus;
for(let key in checkedKeys){
let connectedKeys= Object.keys(this.state.keysCheckedStatus)
.filter(k=> (k.length > key.length) && k.startsWith(key)) || (key.startsWith(k));
for(let connectedKey in connectedKeys){
keysCheckedStatus[connectedKey]=true;
}
}
this.setState({keysCheckedStatus});
}
This is my solution, because my idea is modify treeData with all tree info nodes:
onCheck = (checkedKeys, event) => {
// console.log(this.treeData);
const checkedKey = event.node.props.eventKey;
this.updateItemChecked(checkedKey);
this.setState({ checkedKeys: checkedKeys }, () => {
this.props.parentTree(this.treeData);
});
}
updateItemChecked = (key) => {
var result = getNodeByKey(key, this.treeData);
if (result.type.localeCompare('folder') !== 0) {
if (result.checked === true ) {
result.checked = false;
} else {
result.checked = true;
}
} else {
this.checkIfFolderHasItem(result);
}
}
checkIfFolderHasItem = (result) => {
if ( result.children && result.children.length > 0) {
result.children.forEach( (item) => {
if (item.type.localeCompare('folder') !== 0) {
this.updateItemChecked(item.key);
} else {
this.checkIfFolderHasItem(item);
}
});
}
}
// Expand
onExpand = (expandedKeys, event) => {
// console.log('onExpand', expandedKeys);
const checkedKey = event.node.props.eventKey;
this.updateFolderExpanded(checkedKey);
this.setState({ expandedKeys, autoExpandParent: false }, ()=> {
this.props.parentTree(this.treeData);
});
}
updateFolderExpanded = (key) => {
var result = getNodeByKey(key, this.treeData);
if (result.type.localeCompare('folder') === 0) {
if (result.expanded === true ) {
result.expanded = false;
} else {
result.expanded = true;
}
}
}
render() {
const loop = (data) => {
return data.map((item) => {
if (item.children && item.children.length) {
return <TreeNode title={item.name} key={item.key} checked={item.checked} >{loop(item.children)}</TreeNode>;
}
return (
<TreeNode title={item.name} key={item.key} isLeaf={item.isLeaf} checked={item.checked} />
);
});
};
return (
<div className="draggable-container">
{
// (this.state.showModal) ? <TreeModal show={this.state.showModal} info={this.state.selected} treeData={this.state.treeData} parentTreeModal={this.doParentTreeModal} /> : null
}
<Tree
// Expand
expandedKeys={this.state.expandedKeys}
onExpand={this.onExpand} autoExpandParent={this.state.autoExpandParent}
// Draggable
draggable
onDragStart={this.onDragStart}
onDragEnter={this.onDragEnter}
onDrop={this.onDrop}
// Select && Check
onSelect={this.onSelect}
checkable onCheck={this.onCheck} checkedKeys={this.state.checkedKeys} >
{ loop(this.state.treeData) }
</Tree>
</div>
);
}
JSON Example:
[
{
"name": "Capas1",
"key": "0-23",
"isLeaf": false,
"type": "folder",
"expanded": true,
"children": [{
"name": "sectores",
"key": "0-20",
"isLeaf": true,
"type": "layer",
"checked": true
},
{
"name": "distribucion",
"key": "0-22",
"isLeaf": true,
"type": "layer",
"checked": false
}]
},
{
"name": "Nueva Carpeta0",
"key": "0-624",
"isLeaf": false,
"type": "folder",
"expanded": false,
"checked": false
},
{
"name": "Nueva Carpeta1",
"key": "0-625",
"isLeaf": false,
"type": "folder",
"expanded": true,
"children": [{
"name": "Nueva Carpeta2",
"key": "0-629",
"isLeaf": false,
"type": "folder",
"expanded": true,
"children": [{
"name": "Nueva Carpeta3",
"key": "0-623",
"isLeaf": false,
"type": "folder",
"expanded": true,
"children": [{
"name": "distribucion33",
"key": "0-99",
"isLeaf": true,
"type": "layer",
"checked": true
}]
}]
}]
},
{
"name": "sectores1",
"key": "0-27",
"isLeaf": true,
"type": "layer",
"checked": true
},
{
"name": "sectores12",
"key": "0-89",
"isLeaf": true,
"type": "layer",
"checked": false
},
{
"name": "Capas 2",
"key": "0-588",
"isLeaf": false,
"type": "folder",
"expanded": false,
"children": [{
"name": "Capas 3",
"key": "0-589",
"isLeaf": false,
"type": "folder",
"expanded": false,
"children": [{
"name": "Prueba",
"key": "0-36",
"isLeaf": true,
"type": "layer",
"checked": false
}]
}]
}
]