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

Support nested list (drag item from parent list into nested child list) #1001

Open
josephjesseyoung opened this issue Dec 11, 2018 · 28 comments

Comments

@josephjesseyoung
Copy link

Bug or feature request?

Feature request

Feature request

First of all, amazing work here, kudos to the developers! 👍 👍

I've been using this library to develop a React based UI builder. In my use case, I need the sortable feature to work in a nested element. However I noticed in the readme,

"Independent nested lists - a list can be a child of another list, but you cannot drag items from the parent list into a child list"

Currently, my work around for this problem is to use the combine feature with nested element so that an element could go inside another element in the same hierarchy and be the child of that element. However, again, I also noticed that the combine feature only works on elements in the same hierarchy (ex: items from a list cannot be combined with items from a nested list and vice versa).

Is there a plan for the nested list so that items could be dragged everywhere regardless of the nested list level? I think this could be beneficial for some use case.

Sorry for my bad english 😄 and thanks again! great work! 👍

@markdon
Copy link

markdon commented Dec 11, 2018

This is something I've had to look at too. Instead of having nested droppables/lists you can instead have one droppable with a 'flat' list of all of your draggables and handle their tree/structure separately. This is what I saw @atlaskit/tree doing and have partially built my own implementation.

It makes calculating the new position and parent a bit harder (I haven't done it yet 😅) , but in the end it might give some advantages. Virtualization/Windowing looks easier with a flat DOM tree.

@alexreardon
Copy link
Collaborator

Thanks @markdon!! Yes, that is now @atlaskit/tree works. It is technically a flat structure

@alexreardon
Copy link
Collaborator

It could be nice to create a general guide for how to achieve this

@alexreardon
Copy link
Collaborator

If somebody wants to go on a journey and document it - it would be great to add as a guide to this project

@josephjesseyoung
Copy link
Author

Thanks for the fast reply!! @markdon @alexreardon. Going to try the tree structure and see what I can find

@NeroMorto
Copy link

NeroMorto commented Dec 12, 2018

Hello there!
I'm trying to solve the same problem too.

As it seems to me, within the current functionality, it is possible to keep track where (parent or nested list) is current item is being dropped.
On the other hand, creating nested lists can also be done dynamically, based on a new "combine" feature. The union itself can be tracked through the result object's property combine in onDragEnd method. After that, the combined elements can be rendered as a nested list according to changes in app's state.

But on the way to this solution, I faced a number of problems with the animation of moving items from a nested list to the parent.
At first, I tried my implementation - I came across a problem with animation that I could not to solve.
Then I found that there is an ideologically similar example in StoryBook
I made an example by analogy, and also faced the same problems of animation. After that, I decided to check the problem existence on the original example, and was able to reproduce it.

To reproduce the current situation with an example, it is necessary to remove the type attribute in stories/src/vertical-nested/quote-list.jsx:56 (line number) or make it static (for example, 'list').

<Droppable droppableId={list.id} /* type={list.id} */ key={list.id}>

This is necessary for the droppable zones to be of the same type (if I don’t confuse anything, then this is a requirement for moving elements (draggable) between the droppable zones).

If everything described above is ideologically correct, then I face the following problems. This is not all of them, but the most "visually incorrect".

  1. When you try to move an item from a nested list to parent, the next animation problem appears when the item is not under the cursor.
    This behavior appears only when we want to move the item above the nested list. If you move it down, then everything looks fine.
Screenshot

moving_element_from_nested_list_to_parent

2. There are a number of problems with sorting items (including nested lists).

2.1. Dropout of elements from a nested list when trying to re-sort a nested list within a parent.

Screenshot

reordering_nested_list_with_other_elements_0

2.2. Incorrect behavior of elements under a nested list. With a small movement of the cursor with a nested list, you can see the situation when the elements of the parent list jump by a group or one by one at a time.
Screenshots

reordering_nested_list_with_other_elements_1
reordering_nested_list_with_other_elements_2
reordering_nested_list_with_other_elements_3
reordering_nested_list_with_other_elements_4

3. Sometimes it is difficult to insert an item between a nested list and a parent item.
Screenshot

trying_to_drop_item_from_parent_to_nested_list

Also, in the process of developing the first prototype, I thought about rerendering an element when it is in state isOnDragging, but faced the fact that this is not possible.
It seems to me that it would be helpful for nested list with a large elements count, since in this case it may not be convenient to keep track of the items under this list. An ability to rerender a large list into a small element, with an appropriately sized placeholder (for a new small element) would solve such a problem. And may be in some other cases.

Right now these are the main problems I have encountered.

Thx for your lib and sorry for my English)

@Duohao
Copy link

Duohao commented Mar 14, 2019

http://www.bootcss.com/p/layoutit/ @alexreardon , dnd can not do something like this ?

image

@Haaxor1689
Copy link

Can anyone provide source or at least working example of tree drag and drop with react-beautiful-dnd and @atlaskit/tree?

@markdon
Copy link

markdon commented Apr 4, 2019

Can anyone provide source or at least working example of tree drag and drop with react-beautiful-dnd and @atlaskit/tree?

There's the atlaskit example here.

@atlaskit/tree can't drag between trees, but it doesn't require a huge amount of changes to make it happen. I came up with something that suits my use shown here.

@srph
Copy link

srph commented May 28, 2019

I'm not sure if this has been pointed out before, but this seems to be a valid use-case for nested connected droppables (vertical > horizontal) :

Frame

  • Widget -> New row
  • Widget -> Existing row; new column
  • Column -> New row
  • Row -> New column

I'm sure this is rather complex to implement (plus it's not in the roadmap). Anyway, just leaving this here. Thanks for all your work @alexreardon :).

@bexoss
Copy link

bexoss commented Jun 5, 2019

I was trying to implement these features during a few days, But I couldn't catch up using @atlaskit/tree and react-beautiful-dnd together. But I found a proper project today. For anyone like me I suggest to use this project: https://github.com/frontend-collective/react-sortable-tree. It is able to drag-and-drop over parent-child, and support copy behaviors.

@klickagent
Copy link

I was trying to implement these features during a few days, But I couldn't catch up using @atlaskit/tree and react-beautiful-dnd together. But I found a proper project today. For anyone like me I suggest to use this project: https://github.com/frontend-collective/react-sortable-tree. It is able to drag-and-drop over parent-child, and support copy behaviors.

unfortunately it does not support touch devices properly

@ZakSingh
Copy link

ZakSingh commented Mar 1, 2020

@alexreardon can I ask what the underlying limitation is that prevents dragging from a nested list to an outer list and vice-versa? For our use case it's a requirement (we can't flatten our tree structure due to some other limitations). Most people probably don't need this feature, so we'd be fine forking the library. It would be super helpful if you could point us towards what the cause is so we have a place to start!

Update

What I know so far from playing around with the code:

  • Step one is to set the parent and child list to accept the same type
  • The main issue seems to be that dragging a child list's card up into its parent causes a visual displacement in both the child and parent lists. This is because the card being dragged "teleports" down to be at the relative position it should be at in the parent, but in the child, creating a displacement there too. It's kind of hard to explain, so here's an image. My mouse is where the open space is in the parent:
    image
  • From what I can tell, the marginBox is being calculated incorrectly and teleports the item visually back down to the child list (if I remove the top: property in chrome devtools it goes to (what I think is) the correct position and fixes most of the issues for this case, but of course breaks normal repositioning). Weirdly, as far as I can tell, the redux store has the correct values for displacements/positioning even though there's two simultaneous displacements happening in both the child and parent list. I'm missing something here, but I'm not sure what.
  • As a side note, dragging from a child list down (forwards) into the parent list works perfectly.

So, in summary, it looks like the solution would (at least partially) be an extra case that needs to be handled in wherever the marginBox is calculated, but I can't seem to figure out where that is / how that works.

@Aarbel
Copy link
Contributor

Aarbel commented Apr 28, 2020

@alexreardon do you plan to fix this issue ? Thanks for your help !

@stefanb2
Copy link

stefanb2 commented Aug 5, 2020

Running into the same issue with a recursive data structure of same type of objects, i.e. Object has a property that is of type Object[]. I really I would like to be able to move them between levels :-/

I also have played around with react-dnd and one difference is the nesting behaviour of react-beautiful-dnd Droppable's of the same type=:

<Droppable droppableId="0" type="TYPE" ...>
   ...
   <Droppable droppableId="0.0" type="TYPE" ...>
      ...
   </Droppable>
   ...
   <Droppable droppableId="0.1" type="TYPE" ...>
      ...
      <Draggable draggableId="0.1.0" ...>
         ...
      </Draggable>
      ...
   </Droppable>
   ...
</Droppable>

In the above example Draggable is of TYPE. react-beautiful-dnd will only offer you to drop it into Droppable 0, i.e. the outer Droppable takes priority over any inner one of the same type. Dropping into sibling Droppable's of the same type, i.e. ones that are not wrapped by a Droppable of the same type, works fine.

In react-dnd the behaviour is exactly the opposite: as long as you are within the inner droppable you can drop it there, otherwise it goes to the outer one. (Unfortunately react-dnd has many issues/quirks/bugs under Chrome (or vice versa), which is a deal-breaker for my project...)

I haven't looked into the code, but I'm making an educated guess that when Draggable of TYPE is being dragged then a tree search is performed that stops at the first Droppable of TYPE. Would it be possible to add a property that would enable a depth-first search, i.e. the inner Droppable would take priority over the outer one?

@zlanich
Copy link

zlanich commented Sep 24, 2020

I too desperately need tree support, and the ability to drag items between different levels. I'm seeing that this is still not supported, and I cannot get it to work either. I prefer not to use the Atlaskit tree library, as I'm needing this for various different use cases that don't line up well with that library's opinions. Any update on this? Thanks!

@IlyasArinov
Copy link

+1 here. Would really appreciate this.
As for those who need nested draggable lists asap as I do, it's worth looking into react-sortable-js and react-dnd. These are the examples, that I've found:

Personally, I think i'm gonna explore sortable-js, and hope that someday some genius will figure this one out.

@developerruhul
Copy link

so no hope for a nested/tree-like list in react-beautiful-dnd?

@collab-with-tushar-raj
Copy link

collab-with-tushar-raj commented Dec 8, 2020

@alexreardon I have similar use cases as well and seems this library is not serving those purposes. I am seriously stuck since more than a week now and hoping the developers should come back at least with an honest response even if otherwise. It seems many people across the globe has such use cases and it is high time that these features should get included in the library. I don't understand why this is not a priority ?? It's been 2 years now and people are asking for it.

@hardik98
Copy link

@alexreardon I am also having similar use case. i am using materil ui treeview for nested view and drag and drop is not working for any child treeview item.It's been 2 years now and people are asking for it.

@IlyasArinov
Copy link

@Tush2890 Could be another 2 years until this feature is implemented. I suggest to move on. Check this demo I made that features draggable nested lists using another library (react-sortable-js).

@collab-with-tushar-raj
Copy link

collab-with-tushar-raj commented Dec 11, 2020

@Tush2890 Could be another 2 years until this feature is implemented. I suggest to move on. Check this demo I made that features draggable nested lists using another library (react-sortable-js).

@IlyasArinov I tried your solution and maintained the same hierarchy of DOM nodes as in your demo but after one or two operations, it crashes. After wrapping the parent node with <ErrorBoundary>, this is what I am getting from the library itself :-

image

@IlyasArinov
Copy link

@Tush2890 I am not sure what the problem is. All I can say is that I use this library pretty extensively with infinite nested children lists and dragging from another lists, and It works just fine (except It does not rerender on props change, but there is a workaround for that).

@Harsh298
Copy link

@IlyasArinov does this library support combine feature same as React beautiful dnd provides ?

@IlyasArinov
Copy link

@Harsh298 Not exactly combine feature, but with the original library, on which react-sortable-js is based, you can multidrag using plugins. I haven't tested it, though.

@Harsh298
Copy link

@Harsh298 Not exactly combine feature, but with the original library, on which react-sortable-js is based, you can multidrag using plugins. I haven't tested it, though.

@IlyasArinov what i mean by combine is you can drag Item A and put it over item B when drag and over you can get both item A and B and you can perform move or copy functionality. Like how generally works in google drive or any file managers. Where you can drag folder and combine/merge/move to another folder. So is react sortable js provides that kind of combining functionality where i can get both ids ?

@mmahalwy
Copy link

Still nothing here? :(

@shubham799
Copy link

You can find here for the nested list dragging child from one parent to another.

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

No branches or pull requests