react-sortablejs icon indicating copy to clipboard operation
react-sortablejs copied to clipboard

Missing nested example

Open gregoryforel opened this issue 4 years ago • 29 comments

Hello @waynevanson

Would you happen to have the missing nested example on a codepen or somewhere? It would be great to add it to the examples section.

Thanks in advance

gregoryforel avatar Mar 26 '20 17:03 gregoryforel

@gregoryforel When I rebuild this with hooks I'll add the example.

waynevanson avatar Apr 01 '20 00:04 waynevanson

Thank you for answering! Looking forward to it

gregoryforel avatar Apr 01 '20 17:04 gregoryforel

+1 thanks

jonlepage avatar Apr 04 '20 00:04 jonlepage

@waynevanson can you tell when this will be added?

Antoshkiv avatar Apr 13 '20 11:04 Antoshkiv

A nested example I wrote example

l704863851 avatar Apr 22 '20 10:04 l704863851

Hey, I just wrote a nested sortable this morning.

I used the group prop to do it, you can see the put and pull to have more granular control over whether an item is allowed to be dropped in a certain place. I hope this helps

<ReactSortable
  list={sortedItems}
  setList={onSetList}
  group={{ name: 'root', put: ['nested'], pull: true }}
>
  {sortedItems.map(item => {
    return (
      <div key={item.id}>
        <ReactSortable
          group={{
            name: 'nested',
            pull: true,
            put: ['root', 'nested'],
          }}
          animation="150"
          fallbackOnBody
          swapThreshold="0.65"
          list={item.nestedList}
          setList={onSetNestedList}
        >
          {item.nestedList.map(nestedItem => {
            return <div>{nestedItem}</div>;
          })}
        </ReactSortable>
      </div>
    )}
  )}
</ReactSortable>

karldanninger avatar Apr 22 '20 14:04 karldanninger

I ran into issues with state management, which is why I made it blank at the time. I believe I have some solution, but can't be applied to major version 2 of react-sortablejs.

waynevanson avatar Apr 23 '20 12:04 waynevanson

For whoever ends up needing an nested example, here is one that I made, using l704863851's example: https://codesandbox.io/s/react-sortable-js-nested-tu8nn?file=/src/App.js

IlyasArinov avatar Sep 30 '20 11:09 IlyasArinov

For whoever ends up needing an nested example, here is one that I made, using l704863851's example: https://codesandbox.io/s/react-sortable-js-nested-tu8nn?file=/src/App.js

It helped me! thank you!

823239259 avatar Oct 29 '20 02:10 823239259

I used the group prop to do it, you can see the put and pull to have more granular control over whether an item is allowed to be dropped in a certain place. I hope this helps

For me, it some times throws the error "TypeError: Cannot read property 'props' of null" Screenshot 2020-12-14 at 9 41 04 PM

This is an intermittent issue but I am really unsure about the actual root cause.

collab-with-tushar-raj avatar Dec 14 '20 16:12 collab-with-tushar-raj

If you're using classes, I have an example for you. I'm using recursion to achieve the sorting result.

import React from 'react';
import { ReactSortable, Swap, Sortable } from "react-sortablejs";

export default class List extends React.Component {
    
    constructor (props) {
        super(props);
        this.state = {
            list: [
                {
                    id: "g17201002596u53e7n8dp8m",
                    name: "menu",
                    children: [
                        { id: "g16181002516373h7b8dp8j", name: "shrek", component: "image" },
                        { id: "g1619813226283as3o3xclm", name: "moana", component: "image" },
                        { 
                            id: "g1620327887630yddnv249k", 
                            name: "frozen", 
                            component: "container", 
                            children: [
                                { id: "g16181002516373h7b8dp9t", name: "lion king", component: "image" },
                                { id: "g1619813226283as3o3xc54", name: "toy story", component: "image" },
                                { id: "g1619813226283as3o3xc34", name: "frozen", component: "image" }
                            ]
                        }
                    ]
                },
                {
                    id: "g1727460259hski17n8sjf8",
                    name: "level",
                    children: [
                        { id: "g161810028475373h7b8dp8j", name: "up", component: "image" },
                        { id: "g16198sh5726283as3o3xclm", name: "tangled", component: "image" },
                        { id: "g16203284sf630yddnv249w", name: "snow white", component: "image" }
                    ]              
                }
            ]
        }

        this.sortableOptions = {
            animation: 150,
            fallbackOnBody: true,
            swapThreshold: 0.65,
            ghostClass: "ghost",
            group: "shared"
        };
    }

    //update list recursively
    sortList(currentList, sortedList, parent) {        
        for (let key in currentList) {
            currentList[key] = currentList[key];            
            if(currentList[key].id === parent) {                
                currentList[key].children = sortedList;
            } else {                
                if(currentList[key].children) {                    
                    this.sortList(currentList[key].children, sortedList, parent);
                }
            }
        }
        return currentList;
    }

    //set state
    setList(sortedList, parent) {        
        const list = this.sortList(this.state.list, sortedList, parent);
        this.setState({ list: list });
    }

    //creating list item function
    createItem(child) {  
        let listItem = null;                    
        switch(child.component) {            
            case 'container': 
                listItem = <ul key={ child.id }>
                    {
                        (child.children) ?
                        <ReactSortable
                            { ...this.sortableOptions }
                            list={ child.children }
                            parent={ child.id }
                            setList={
                                (sortedList, element) => {
                                    if(element) this.setList(sortedList, element.options.parent);
                                }
                            }
                        >
                        {
                            child.children.map((item) => this.createItem(item))
                        }
                        </ReactSortable>   
                        : <li></li>
                    }
                </ul>
            break
            default:
                listItem = <li key={ child.id }>{ child.name }</li>
        }
        return listItem;
    }

    //creating list function
    createList(list) {
        return list.map((child) => {                    
            return(
            <li key={ child.id }>  
                { child.name }
                <ul>
                    <ReactSortable
                        { ...this.sortableOptions }                                       
                        list={ child.children }
                        parent={ child.id }
                        setList={
                            (sortedList, element) => {
                                if(element) this.setList(sortedList, element.options.parent);                                    
                            }
                        }                
                    >
                    {
                        child.children.map((item) => {
                            return this.createItem(item);                                        
                        })
                    }
                    </ReactSortable>
                </ul>
            </li>
            )
        });
    }

    //render the component
    render() {
        return(
            <ul>{ this.createList(this.state.list) }</ul>
        )
    }
}

camilacanhete avatar May 18 '21 15:05 camilacanhete

@IlyasArinov

For whoever ends up needing an nested example, here is one that I made, using l704863851's example: https://codesandbox.io/s/react-sortable-js-nested-tu8nn?file=/src/App.js

Can we make the child from one container not dropped in another

skvanniarajan avatar Nov 25 '21 07:11 skvanniarajan

@IlyasArinov

For whoever ends up needing an nested example, here is one that I made, using l704863851's example: https://codesandbox.io/s/react-sortable-js-nested-tu8nn?file=/src/App.js

Can we make the child from one container not dropped in another

Yeah, use different group name or put, pull

IlyasArinov avatar Nov 25 '21 09:11 IlyasArinov

I wrote a nested example referring to these cases, but nesting will cause reference relationships, I do not understand how the internal operation, can you help me

https://codesandbox.io/s/winter-rain-9gv5y3?file=/src/App.js

yanghuanrong avatar Mar 12 '22 06:03 yanghuanrong

@IlyasArinov or anyone else, if you have a nested example for sortable in Vue.js. Kindly share it.

Zaimbinjawaid avatar Jul 27 '22 10:07 Zaimbinjawaid

Has anyone managed to fix the react 18 duplication issue?

In the example provided by @IlyasArinov https://codesandbox.io/s/react-sortable-js-nested-tu8nn?file=/src/App.js There is a bug when you drag an item from a container one level up. For example, if you drag text: item 8 under container: item 2. the original item 8 will stay in place but a new one will be created under item 2. The same happens when you drag a nested container to the root level.

Have been struggling with how to fix this issue.

bonttimo avatar Aug 29 '22 21:08 bonttimo

There is a bug when you drag an item from a container one level up. For example, if you drag text: item 8 under container: item 2. the original item 8 will stay in place but a new one will be created under item 2. The same happens when you drag a nested container to the root level.

@bonttimo dunno if still relevant but if you haven't fixed it yet I am working on fixing it. I see the issue

bytewiz avatar Oct 17 '22 13:10 bytewiz

@bytewiz Did you finish it?

Heilemann avatar Dec 24 '22 02:12 Heilemann

Has anyone managed to fix the react 18 duplication issue?

In the example provided by @IlyasArinov https://codesandbox.io/s/react-sortable-js-nested-tu8nn?file=/src/App.js There is a bug when you drag an item from a container one level up. For example, if you drag text: item 8 under container: item 2. the original item 8 will stay in place but a new one will be created under item 2. The same happens when you drag a nested container to the root level.

Have been struggling with how to fix this issue.

Any chance you found a fix for this?

Heilemann avatar Dec 26 '22 12:12 Heilemann

Has anyone managed to fix the react 18 duplication issue?

In the example provided by @IlyasArinov https://codesandbox.io/s/react-sortable-js-nested-tu8nn?file=/src/App.js There is a bug when you drag an item from a container one level up. For example, if you drag text: item 8 under container: item 2. the original item 8 will stay in place but a new one will be created under item 2. The same happens when you drag a nested container to the root level.

Have been struggling with how to fix this issue.

Any updates on the issue?

Marius-AdamDT avatar Feb 01 '23 11:02 Marius-AdamDT

I also have the same problem, I have tried something like using flushSync but it doesn't seem to work well. It took me a while, here's how I fixed it.

SOLVE IDEA: rearrange the orders of changes (stacking changes order and executed the order with deeper elements first). chrome-capture-2023-2-7

This is my sandbox Edit react-sortablejs-nested

VuHuuTuan avatar Mar 07 '23 07:03 VuHuuTuan

flushSync

Can you share the code?

pawpaw2022 avatar Mar 18 '23 02:03 pawpaw2022

@pawpaw2022

Can you share the code?

Sandbox link added (https://github.com/SortableJS/react-sortablejs/issues/134#issuecomment-1457692418). Look at my /src/groupTree/GroupTree.tsx/handleSetGroups you can see my flushSync attemp at 2.. (Worked but cause warning "flushSync was called from inside a lifecycle") (My demo currently worked without problem at 3.)

VuHuuTuan avatar Mar 20 '23 02:03 VuHuuTuan

Your code completely works fine but only for the single root it is not working for the multiple root as in one root drag to make the child of another root

sagun-k avatar Oct 11 '23 10:10 sagun-k

I also have the same problem, I have tried something like using flushSync but it doesn't seem to work well. It took me a while, here's how I fixed it.

SOLVE IDEA: rearrange the orders of changes (stacking changes order and executed the order with deeper elements first). chrome-capture-2023-2-7 chrome-capture-2023-2-7

This is my sandbox Edit react-sortablejs-nested

Works fine can you modify it so we can add multiple parents?

fineshop avatar Nov 08 '23 11:11 fineshop

@sagun-k @fineshop

Your code completely works fine but only for the single root it is not working for the multiple root as in one root drag to make the child of another root

Works fine can you modify it so we can add multiple parents?

I was fixed it a bit to work on multiple root base on groupname, good luck. chrome-capture-2023-10-9 New sandbox Edit react-sortablejs-nested (forked)

edit: reup gif

VuHuuTuan avatar Nov 09 '23 02:11 VuHuuTuan

@sagun-k @fineshop

Your code completely works fine but only for the single root it is not working for the multiple root as in one root drag to make the child of another root

Works fine can you modify it so we can add multiple parents?

I was fixed it a bit to work on multiple root base on groupname, good luck. chrome-capture-2023-10-9 New sandbox Edit react-sortablejs-nested (forked)

Thank you for this.

fineshop avatar Nov 09 '23 03:11 fineshop

Hey, I just wrote a nested sortable this morning.

I used the group prop to do it, you can see the put and pull to have more granular control over whether an item is allowed to be dropped in a certain place. I hope this helps

<ReactSortable
  list={sortedItems}
  setList={onSetList}
  group={{ name: 'root', put: ['nested'], pull: true }}
>
  {sortedItems.map(item => {
    return (
      <div key={item.id}>
        <ReactSortable
          group={{
            name: 'nested',
            pull: true,
            put: ['root', 'nested'],
          }}
          animation="150"
          fallbackOnBody
          swapThreshold="0.65"
          list={item.nestedList}
          setList={onSetNestedList}
        >
          {item.nestedList.map(nestedItem => {
            return <div>{nestedItem}</div>;
          })}
        </ReactSortable>
      </div>
    )}
  )}
</ReactSortable>

Can you please share the full code ??

srikanth-perisync avatar May 02 '24 12:05 srikanth-perisync