minop1205/react-dnd-treeview

Data order

gsavci opened this issue · 5 comments

When I drag elements, they appear in the right place. But when I print to the console, the order get mixed up. How can I sync data in the same order as on the screen?
For example when I render my data it looks like it:

  Parent
     Children 1
     Children 2
              Sub-children

But when I write data to console, the order is :

Sub-children, Parent, Children 1, Children 2.

How can I sort data to make right order?

@gsavci The order of the tree is controlled by the sort property and insertDroppableFirst. See the README for details on these properties.

Setting both to false, as in the following example, will cause the order of the nodes to follow the order of the data array passed to the tree property.

      <Tree
        {... .someProps}
        tree={treeData}
        sort={false}
        insertDroppableFirst={false}
     />

First of all thanks for your quick answer.

Both sort and insertDroppableFirst properties are already set false.

@gsavci

As it turns out, it is not possible to make the sequence of data exactly equivalent to the sequence on the display.
This is due to the display logic of the tree and is intentional, not a bug.

If the sort property and insertDroppableFirst are false, then children with the same parent are compared for order of occurrence, but Indexes on other nodes are ignored.

This is fine on the tree display.

It is possible to move data to a position on the display rather than to the first index, but this would require a more complex implementation.
This is why we are currently using a simple implementation.

For example, if all nodes are directly under the root, the order of the data is equal to the order in which they are displayed.

2022-11-03_18h05_36

So, moving File 3 to Folder 2-1 moves File 3 to the top of the data array.

2022-11-03_18h06_09

As a point of reference, I would like to ask, why is it necessary to match the data array to the order on the display?
I myself don't understand the need for this and would like to know what use cases there are.

I want to use the structure I created with this component as a tree structure in a different component. So I need to know the proper order of children of a node.

@gsavci

I believe that a good way to address this issue is to create a custom function to reorder the tree data into an arbitrary order.

Create a custom function as follows

type SortFn = (
  treeData: NodeModel<CustomData>[],
  sortedData: NodeModel<CustomData>[],
  parentId: NodeModel["id"]
) => void;

const sortTreeData: SortFn = (treeData, sortedData, parentId) => {
  const children = treeData.filter((node) => node.parent === parentId);

  children.forEach((node) => {
    sortedData.push(node);
    sortTreeData(treeData, sortedData, node.id);
  });
};

Apply this function in the onDrop callback.

  const handleDrop = (newTreeData: NodeModel<CustomData>[]) => {
    const sortedData = [];
    sortTreeData(newTreeData, sortedData, 0);
    setTreeData(sortedData);

    console.log(sortedData.map((node) => node.text));
  };

image

See below for an actual sample.
https://codesandbox.io/s/issue-166-gqdrvy?file=/src/App.tsx:1033-1260

Please try it.