Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to get parentKey to add new node #49

Closed
anil1712 opened this issue Feb 3, 2017 · 14 comments
Closed

How to get parentKey to add new node #49

anil1712 opened this issue Feb 3, 2017 · 14 comments

Comments

@anil1712
Copy link

anil1712 commented Feb 3, 2017

Hi,
First of all I really like your implemented stuff, it saves my lot of time. So thanks for implementing this sortable tree, but it would be more better if you can make the documentation more descriptive.
Because I am having issue while using the Data Helper Functions. I am trying to use the addNodeUnderParent(treeData, newNode, parentKey) but dont know how to get the parentKey.

Also I did not the use of getNodeKey parameter, so can you please explain these thing with some example.

Actually I am pretty new for React. So please help me to get out of it.

@fritz-c can you please look into it.

Thanks

@imyagnesh
Copy link

Hi,

Can you provide example for AddNodeUnderParent and removeNodeAtPath i am trying to add and remove
node in generateNodeProps property.

@anil1712 : Please let me know if you found any work arround.

Thanks in advance.

@anil1712
Copy link
Author

anil1712 commented Feb 7, 2017

@yagneshmodh Right now I am just using addNodeUnderParent. Here is the working code.

..................
import {addNodeUnderParent} from 'react-sortable-tree';
..................
let NEW_NODE = {title: 'Another Node', subtitle: 2}
let newTree = addNodeUnderParent({
        treeData: this.state.treeData,
        newNode: NEW_NODE,
        expandParent: true,
        parentKey: 0, // Still don't know where to get the parentKey
        getNodeKey: ({node: TreeNode, treeIndex: number}) => {
            return treeIndex;
       },
 });
 this.setState({treeData: newTree.treeData});

Let me know if you got any solution to pass the parentKey

@anil1712
Copy link
Author

@fritz-c Can you please look into this?

@vladimirsvsv77
Copy link

try this code:

    addNode(rowInfo){
        let NEW_NODE = {title: 'Another Node', subtitle: 2};
        let {node, treeIndex, path} = rowInfo;
        path.pop();
        let parentNode = getNodeAtPath({
            treeData: this.state.treeData,
            path : path,
            getNodeKey: ({ treeIndex }) =>  treeIndex,
            ignoreCollapsed : true
        });
        let getNodeKey = ({ node: object, treeIndex: number }) => {
            return number;
        };
        let parentKey = getNodeKey(parentNode);
        if(parentKey == -1) {
            parentKey = null;
        }
        let newTree = addNodeUnderParent({
                treeData: this.state.treeData,
                newNode: NEW_NODE,
                expandParent: true,
                parentKey: parentKey,
                getNodeKey: ({ treeIndex }) =>  treeIndex
         });
         this.setState({treeData: newTree.treeData});
    }

It's works fine for me.

@fritz-c
Copy link
Member

fritz-c commented Feb 12, 2017

Sorry for the delay.

What action initiates the node addition? i.e., are you clicking on a button on the parent to add a child, are you adding nodes programmatically to parent nodes that fit certain conditions, etc? The way to do it will depend on that.

@anil1712
Copy link
Author

Very very thanks @fritz-c Its working prefect.

@beratuslu
Copy link

guys nobody has explained where to get parentKey to add new node? in my case I am triggering an action from inside custom node renderer.

@everyonesdesign
Copy link

I wrote a small helper function to get the parent. I know it's not that efficient, because it walks every node of the tree even after it has found the parent, but anyway:

function getNodeKey(node) {
  return node.id;
}

function getParent(childNode, treeData) {
  let parent = null;

  walk({
    treeData,
    getNodeKey,
    ignoreCollapsed: false,
    callback: ({ node }) => {
      if (find(node.children, { id: getNodeKey(childNode) })) {
        parent = node;
      }
    },
  });

  return parent;
}

You may want to alter getNodeKey function depending on your tree structure.

@borisyordanov
Copy link

@vladimirsvsv77 What is getNodeAtPath()? Is that a system function? If you wrote it yourself can you post your code?

@borisyordanov
Copy link

@everyonesdesign I don't understand your function. How do you just call walk(), isn't that a method of the treeData? Is it a custom method you implemented?

What about find()? Where did that come from?

@everyonesdesign
Copy link

everyonesdesign commented Nov 21, 2017

@borisyordanov
walk is a utils method provided by react-sortable-tree.
It can be directly imported from it, e.g.

const { walk } = require('react-sortable-tree');

You can find other helpful functions in src/utils/tree-data-utils.js.
As for find method, I use the method from Lodash library, but you can also use native Array.prototype.find (in case you don't support IE or polyfill the method).

if (node.children.find(child => getNodeKey(сhild) === getNodeKey(childNode))) {
  parent = node;
}

@borisyordanov
Copy link

borisyordanov commented Nov 22, 2017

@everyonesdesign Thanks for taking the time to explain. I do have another question - if you need to get the parent of the node, why don't you use the path? If your path = [2,3,1], then the parent should be treeData[2].children[3] ?

Edit: i guess what i posted above is true, but that info doesn't necessarily make finding the parent easier. I ended up using a slightly modified version of your function. Thanks for the help!

@stephencarr
Copy link

Late to the game, but @borisyordanov import { getNodeAtPath } from 'react-sortable-tree'

@metalalive
Copy link

metalalive commented Mar 31, 2021

guys nobody has explained where to get parentKey to add new node? in my case I am triggering an action from inside custom node renderer.

The parentKey comes from the property generateNodeProps in your SortableTree component , generateNodeProps points to any function with arguments {node, path} and expects to return an a object with fields like {title: YOUR_NODE_TITLE, buttons:[BUTTON1, BUTTON2 , ......]} which is used for renderring each node . For example , your render code may look like this :

 render() {
        return <SortableTree isVirtualized={ false }
                treeData={this.state.treeData}
                onChange={this.on_state_change.bind(this)}
                generateNodeProps={
                    ({node, path, treeidx}) => ({
                        title: node.title,
                        buttons: [
                            <button data-node_key_path={ path.join(',') }
                                onClick={ this.update_tree_status.bind(this) }>
                                edit
                            </button> ,
                        ],
                    })
                }
            /> ;
    } // end of render function

The argument path in the property generateNodeProps is actually a list of tree index numbers for each node to represent a path from a root node to that node in current tree view , Note that the path of each node also changes as soon as you expand or collapse any non-leaf node in the tree view, then Sortable re-calculates path and re-render the buttons for each present node in updated tree view .

To me, it may be good practice to preserve path from generateNodeProps to the buttons (in the example, the path is serialized and store to dataset of the HTML element) , used at later time for any operation on the tree.

Hope that helps, since it is not clearly documented.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants