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

drag & drop #12

Open
denkomanceski opened this issue May 9, 2017 · 12 comments
Open

drag & drop #12

denkomanceski opened this issue May 9, 2017 · 12 comments

Comments

@denkomanceski
Copy link

denkomanceski commented May 9, 2017

I am trying to make the tree drag/droppable but no matter what, it doesnt start working.. I have a custom rowRenderer which sets the treeNodeAttributes to true, the tree has droppable: true (I also tried setting it up as an object (I cant even get a console.log). I am using my own custom click handler (tree.on('click), but even if I dont, and comment it out, I still cant make it drag.. the example https://infinite-tree.js.org/examples.html#/classic works, but its still hard to start a drag process.. any idea how should I fix this issue ? dragging will be the main feature in the app..

thanks

Edit: this tree has a nice drag/drop functionalities, but the other features are not as good as this infinite tree (https://angular2-tree.readme.io/docs)

@cheton
Copy link
Owner

cheton commented May 9, 2017

So far infinite-tree can only drag an external element into the tree. Moving between nodes is not supported in current versions. Do you want to drag and drop nodes inside the tree?

@denkomanceski
Copy link
Author

@cheton thanks for the quick response.. ye, I would like to move nodes inside the tree.. change parents, etc.. is it hard to implement this ?

@cheton
Copy link
Owner

cheton commented May 9, 2017

To make a node draggable, you can set the attribute draggable="true" (note. "true" is string, not boolean true) in your custom rowRenderer, this allows to drag an element and drop to a target node. You can also use getNodeFromPoint(x, y) on dragstart to get the node, and then call moveNodeTo(dragNode, parentNode, index) on drop. Here comes my screenshot:

2017-05-09 21 43 09

If you want to drag a node and then insert it between two nodes, I'm not sure if it's easy to do, you might need to get current mouse position to determine if it is necessary to add/remove a ghost element above or below a node.

@denkomanceski
Copy link
Author

Thanks for the advice, but creating a ghost element will require adding/removing 'node' (the ghost node) very fast from the tree right ? Also, how can I determine between which nodes should I put the ghost node

ty

@denkomanceski
Copy link
Author

Any new cool idea on this ? we really miss dnd :|

@cheton
Copy link
Owner

cheton commented Jun 8, 2017

Sorry for the delay. I have some ideas about how to add dnd support, but I'm pretty busy with my day work in this moment. I will make some updates once I'm free.

@denkomanceski
Copy link
Author

denkomanceski commented Jun 15, 2017

Okay, thanks.. we are waiting, because we have no clue how to do it properly :)

@denkomanceski
Copy link
Author

@chenton, could you please briefly explain the idea that you have (or some simplest idea) on how to implement this dnd feature into the tree? we did some workaround with "cut" and "paste", but this way is not really UX friendly :(

@cheton
Copy link
Owner

cheton commented Jun 20, 2017

@denkomanceski

I just updated the sample code in the examples directory, you can check out https://github.com/cheton/infinite-tree/blob/master/examples/default/index.js#L250-L329 for my initial work regarding drag and drop support. Note that the functionality is still not ready yet, just demonstrated a basic concept within the demo.

let ghostElement = null;
let draggingX = 0;
let draggingY = 0;

The ghostElement is the pseudo element when you want to insert between two nodes, it will be added or removed when dragging. The draggingX and draggingY remember the last position when dragging over an element.

To determine whether you're dragging from top to bottom or from bottom to top, you need a delta value to check whether the value is positive or negative, like so:

const movementX = event.x - (Number(draggingX) || event.x);
const movementY = event.y - (Number(draggingY) || event.y);

For the above I haven't finished this part due to my busy day work, you can continue to work if you're free.

@denkomanceski
Copy link
Author

This works great.. I cant see anything missing, besides how to know where I am dropping the node (below, inside, above). Thank you for this!

@denkomanceski
Copy link
Author

denkomanceski commented Jun 20, 2017

is this a viable way to find out where the node is being dropped? getNodeFromPoint(x, y)

Edit: It seems that using getNodeFromPoint is okay if the drag is on some node, which means the node that is dragged, will be a child to that one, but what happens for above/below, to find the index or something

Edit2: The hard part here is that the tree is not nested (but flat), so sometimes when I try to put the node as a last child, the insertBefore is actually the node after the parent of that node. Also, its impossible to put a node as a last node in the tree (the very last on the tree), because there isnt what to insertBefore on

@cheton
Copy link
Owner

cheton commented Jun 20, 2017

I think you might need to remember the parentNode and the insertIndex in the dragover event, and then call tree.moveNodeTo(dragNode, parentNode, insertIndex) on drop for the case of inserting above or below a node.

  1. For the case of inserting above a node:

    el.parentNode.insertBefore(ghostElement, el);

    Use this sample code to find the parentNode and the insertIndex when inserting above the el:

    // dragover
    const id = el.getAttribute(tree.options.nodeIdAttr);
    const node = tree.getNodeById(id);
    const parentNode = node.parent;
    const insertIndex = parentNode.children.indexOf(node);
  2. For the case of inserting below a node:

    el.parentNode.insertBefore(ghostElement, el.nextSibling);

    Use this sample code to find the parentNode and the insertIndex when inserting below the el:

    // dragover
    const id = el.getAttribute(tree.options.nodeIdAttr);
    const node = tree.getNodeById(id);
    const parentNode = node.parent;
    const insertIndex = parentNode.children.indexOf(node) + 1;

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

2 participants