angular/components

drag-drop: Dropping into nested ChildList

ked1 opened this issue ยท 31 comments

ked1 commented

Bug, feature request, or proposal:

Bug, Feature depending on the expectation, which isn't totally clear in this case.

I would tend to say, it is a bug, because my use case seams to be quite common.

What is the expected behavior?

It should be possible to drag and drop from a parent list into a nested child list.

What is the current behavior?

No placeholder is displayed in the child list and the received container in the drop event method is always the parent list. The placeholder moves only in the parent list, which is consistent to the described drop event data.

What are the steps to reproduce?

https://stackblitz.com/edit/angular-dragdrop-from-parent-to-nested-childlist
Drag parent item into the subitem list.

(From subitem list to parent list works correctly)

What is the use-case or motivation for changing an existing behavior?

We have a component to configure menu structure by drag and drop. It should be possible to move menu items to a sub menu.

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

@angular/cdk 7.0.3

Is there anything else we should know?

In our use-case we have only one element with a child list, which could be possible to solve with the current implementation assuming it is a bug. I'm struggling by the imagination with multiple child lists according to the concept with template variables.

@jelbourn @crisbeto
Hey guys, I have a similar use case and it would be great, if you'd have some hints for us to work around this problem.

(similar issue here #13242)

ked1 commented

Did someone find a workaround for this?
For us It would be great to finally integrate our feature branch which introdurces the CDK to our app. But this issue is a show stopper at the moment.

I've also run into this when working on a drag-drop category tree editor component with @angular/cdk@7.1.0

As you can see in this video, it is possible to drag into a nested list, but it is just exceedingly difficult. There's probably a 1-pixel window which you must land on in order for it to work.

ezgif-1-542fe60bba71

I've not looked at the implementation, but visually it looks like the lower cdkDrag will switch position as soon as the cdkDragPlaceholder crosses its top boundary. Perhaps allowing the reordering to occur after <x pixels/percent> overlap of that item might make it possible to ergonomically drag into a nested list?

ked1 commented

I just recognized, that my stackblitz has an issue. The parentList is connected to non-existing childList property. But still I'm not sure how to fix it and if it would work.

@michaelbromley : thanks for your input. Could you provide your sample on stackblitz?

Noticed the merged #14257 into master/7.2.0.
The above stackblitz examples look better. Moving items into other child's still shows issues.

7.2.0 seems to get make everything a bit less jittery (if you update @michaelbromley stackblitz for example), but now child/nested items aren't able to become parent/top level items, and now completely unable to become part of another nested/child group.

@MarkPieszak
Tried to identify the problem with the above example, but couldn't find it.

The example generates nested cdkDropListGroup. This might only work for the DropList's in the group not transfering to one List from another Group. Deleted the cdkDropListGroup in app-product-category-tree and made one in app.html, still didn't work.

[cdkDropListEnterPredicate] does not show any events in @7.2.0.

With @7.2.0 in my application (WYSIWIG ngx-formly based form designer) where I use nested childs to group form fields and for horizontal layouting I can move and transfer between all lists.

Still jitter exists, when setting up cdkDropListEnterPredicate and moving over a parent and child many calls are made. Here material should only take the child into account.

I adapted @michaelbromley example https://stackblitz.com/edit/material2-14093-qwaobp to use a drag registration service.

Removed cdkDropListGroup in product-category-tree.
Each tree-node wraps a CdkDropList, with AfterContentInit it registers to the drag registration service.
In the html [cdkDropListConnectedTo]="dropListConnectedTo" is used for allowed list to drag into, the method returns all registered CdkDropList.

Now items can be transferred, although it needs some mouse moving to accomplish a transfer.

There is still a lot of jitter, as the CDK enables all CdkDropList under the mouse, instead of only offering the deepest (highest z-index) child.

I think, transfers are failing because of the size of draggable and the destination. Therefor moving to the deepest child is not possible.

In my own application, I don't have problems transferring to the first/last position, in this example I have problems, especially to the first position.

tested with cdk@7.3.1

Hoping to get some feedback and pin-pointing the remaining problems for fixing.

For background information: I use an adapted registration service, to register different ListGroups (e.g. main and template), where I allow to copy from template to main, but not the other way around and allowing to transfer/move in main and template themself.

Any news here?

We are willing to offer a bounty if anyone can get this done, $500 to do it.

We are willing to offer a bounty if anyone can get this done, $500 to do it.

Challenge accepted

We need exactly this so that we can drag items in and out of grouped list in our app. Looking forward for a solution.

Not a solution, but an alternative is ngx-drag-drop. It's demo link has nested lists.

Guys, please check out my solution - I was able to achieve the described behavior using the latest (8.0.x) version of Angular CDK:
https://stackblitz.com/edit/angular-cdk-nested-drag-drop-demo
Try to nest list items in other ones.

@ipakhomov It certainly works for nesting ๐Ÿ‘

But I cannot seem to reorder. Is it just that you didn't implement reordering logic?

@michaelbromley yup, reordering is not handled right now, but I suppose it's possible to implement. I just tried to reproduce expected in the issue behavior:

It should be possible to drag and drop from a parent list into a nested child list.

@ipakhomov So I guess you could say with version 8 all the funky glitches have been fixed, so nested drag and drop is totally viable without any unusual hacks right? (I'm checking out the stack-blitz now, looks great :D)

@bradtaniguchi Yes, it seems that described by @michaelbromley issue was fixed in the last updates, so we don't need to do anything hacky to implement nested drag-n-drop ๐Ÿ˜‰

ked1 commented

Guys, please check out my solution - I was able to achieve the described behavior using the latest (8.0.x) version of Angular CDK:
https://stackblitz.com/edit/angular-cdk-nested-drag-drop-demo
Try to nest list items in other ones.

Yes indeed, your example seems to work well. I can't proof it on my original "real world" case, because the project is not on my todo list anymore.

@michaelbromley @FritzHerbers @MarkPieszak @djcurfew @johannesheucher Do you agree with me to close this issue?

@crisbeto Thanks for your great contributions on the Angular CDK!

@ked1 I just tested with @angular/cdk v8.0.2 and following the example from @ipakhomov I can indeed get nesting to work!

Now I just need to wait for automatic scrolling to land and I can implement this in my app ๐ŸŽ‰

Thanks @ipakhomov, I'll check out your solution. I wish though something simple as this worked out of the box:
https://stackblitz.com/edit/angular-drag-and-drop-child-groups

Hey,
after reading the comments here i was optimistic to get nested drag and drop to work with material drag and drop. For me drag drop between parent and nested lists with sorting did not work. Whenever i try to sort inside a nested list, the placeholder appears in the parent list.

I would love to use the default material drag and drop implementation, because its working great in other usecases for me. If someone managed to get this case working with material drag and drop, it would be nice to get the info how?!

Anyway i needed an implementation asap for our project, thats why i wrote yesterday my own drag and drop implementation, which is working with nested lists.
(i created a POC showcase. this code is not polished or tested etc. today)

if someone has also the same usecase watch the demo, the is a contact link. (if there is enough inter. ill investigate the time to extract the code and create a public library)

https://priemar.github.io/pri-ng-dragdrop-showcase/

@djcurfew is that what you need ?!

@Priemar it looks like good.

The solution of @Priemar resolve this issue I agree.
But that came with a lot of complexity to handle the reordering. Has someone come to a solution?

@fatalcaron my implementation is similar to the material implementation.

You can set a data object for the dragItem and a dataItem for the droplist.

In the dropList -> dropEvent you will get the

  • sourcelist data item
  • targetlist data item
  • target list drop index
  • drag item data".

So you can simply remove the item from the sourcelist and add it in to the target list at the given drop index.

I think thats straight forward and not complex.

For a good performance i recommend using trackBy for the *ngFor and onPush changedetection. With those mechanisms the performance is good (sure it depends on the scenario).

Anyway at the moment there is not much need for this libarary as it looks like. So i currently will not investigate the time to extract and put the library to npm. (maybe it changes in the future, then i can contact you @fatalcaron )

cheers

Really sorry, I wanted to mention the solution of @ipakhomov

@michaelbromley yup, reordering is not handled right now, but I suppose it's possible to implement. I just tried to reproduce expected in the issue behavior:

It should be possible to drag and drop from a parent list into a nested child list.

This solution resolved my use case, but sorting needs to be implemented.
@ipakhomov , Could you provide some clue regarding how to integrate reordering with your solution.

As i wrote above i created a lib. for nested drag and drop: (bec. of time issues its currently not a release version) but maybe someone needs an alternative until the angular/material drag drop is working correctly.

https://www.npmjs.com/package/pri-ng-dragdrop

We are willing to offer a bounty if anyone can get this done, $500 to do it.

Are you still paying for it? I got the solution.

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.