Reputation: 305
I am using 'react-sortable-tree' library to build a hierarchy of child. I am trying to modify the functionality of the playground: https://frontend-collective.github.io/react-sortable-tree/storybook/?selectedKind=Basics&selectedStory=Add%20and%20remove%20nodes%20programmatically&full=0&addons=0&stories=1&panelRight=0'
What I want, is when I click on 'Add Child' button, it open up a new text box. After inserting the text inside that text box, it should get updated as a new node instead of the default array provided with the library.
This is what I have tried to achieve so far:
import 'react-sortable-tree/style.css';
import React, { Component } from 'react';
import SortableTree, { addNodeUnderParent, removeNodeAtPath } from 'react-sortable-tree';
const firstNames = [
'Abraham',
'Adam',
'Agnar',
'Albert',
];
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
treeData: [{ title: 'Peter Olofsson' }, { title: 'Karl Johansson' }],
addAsFirstChild: false,
inputChange: false,
childName: ''
};
}
handleChange =()=>{
const currentState = this.state.inputChange;
this.setState({ inputChange: !currentState });
}
setValue = (e) => {
this.setState({
childName: e.target.value
})
}
handleSubmit = (e) => {
e.preventDefault();
console.log('A name was submitted: ' + this.state.childName);
this.setState({
inputChange: false
})
}
render() {
const getNodeKey = ({ treeIndex }) => treeIndex;
const getRandomName = () =>
//firstNames[Math.floor(Math.random() * firstNames.length)];
<form>
<label>
Name:
<input type="text" name="name" />
</label>
<input type="submit" value="Submit" />
</form>
return (
<div>
<div style={{ height: 300 }}>
<SortableTree
treeData={this.state.treeData}
onChange={treeData => this.setState({ treeData })}
generateNodeProps={({ node, path }) => ({
buttons: [
<button
onClick={
// this.setState(state => ({
// treeData: addNodeUnderParent({
// treeData: state.treeData,
// parentKey: path[path.length - 1],
// expandParent: true,
// getNodeKey,
// newNode: {
// title: `${getRandomName()} ${
// node.title.split(' ')[0]
// }sson`,
// },
// addAsFirstChild: state.addAsFirstChild,
// }).treeData,
// }))
this.handleChange
}
>
Add Child
</button>,
<button
onClick={() =>
this.setState(state => ({
treeData: removeNodeAtPath({
treeData: state.treeData,
path,
getNodeKey,
}),
}))
}
>
Remove
</button>,
],
})} />
</div>
{this.state.inputChange === true ? <form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" name="name" value={this.state.childName} onChange={this.setValue} />
</label>
<input type="submit" value="Submit" />
</form>
: null}
</div>
);
}
}
The text box value is getting updated but I am not able to handle that updated state into the component . Please help to get through this.
Upvotes: 0
Views: 3138
Reputation: 532
If You replace this part of Your code:
<button
onClick={
// this.setState(state => ({
// treeData: addNodeUnderParent({
// treeData: state.treeData,
// parentKey: path[path.length - 1],
// expandParent: true,
// getNodeKey,
// newNode: {
// title: `${getRandomName()} ${
// node.title.split(' ')[0]
// }sson`,
// },
// addAsFirstChild: state.addAsFirstChild,
// }).treeData,
// }))
this.handleChange
}
>
Add Child
</button>,
with this:
<button
onClick={
() => this.setState(state => ({
treeData: addNodeUnderParent({
treeData: state.treeData,
parentKey: path[path.length - 1],
expandParent: true,
getNodeKey,
newNode: {
title: `${getRandomName()} ${
node.title.split(' ')[0]
}sson`,
},
addAsFirstChild: state.addAsFirstChild,
}).treeData,
}))
}
>
Add Child
</button>,
then everything will work as expected. I guess You missed to pass a function to onClick event of button..
// this.setState(state => ({
becomes
() => this.setState(state => ({
Hope it's not late:)
Upvotes: 1