-
Notifications
You must be signed in to change notification settings - Fork 6.8k
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
cdk-drop: allow drag-and-drop copy behavior #13100
Comments
Could my issue be related to yours? All i am trying is to "copy" new items to my dropzone. |
@kanidjar seems like the same issue Look at the |
Confirmed. Using your workaround fixes my issue :) |
I am also facing the same issue, |
When dropped inside B or C, you could temporarily call a method inside A that "resets" the array of items being displayed inside a timeout of 0 ms. |
We used to have an issue where an item that was dragged into another container wasn't being reverted, however that has been resolved in 7.0.0-beta.1. What other issues are you running into? |
Hey @crisbeto and @eden6 , Thanks for your response. Once again thanks a lot for your responses. 👍 |
@SAkhil95 That's what I had understood. I don't know if a copy will be implemented, but in the meantime if you catch the |
@SAkhil95 are you also copying the object in your data model after the element has been dropped? |
I have created a simple Stack blitz demo , I just want the items in List A to be copied to List B rather than move. |
Here's what I was talking about: |
@eden6 you don't need to hack around it with timeouts and resetting the list. You just have to push the item to the new list without removing it from the old one: https://stackblitz.com/edit/angular-ymlmql. Closing the issue since this seems to work now. |
@SAkhil95 I'm not sure if there is an event for dropping outside of a You'll need to determine what kind of |
Yes @arlowhite , I was thinking the same to push items back to main List , that will suffice the delete functionality. Thanks you very much. |
@crisbeto @arlowhite |
I’m not sure I completely get the use case. Are you asking whether it’s possible to disable sorting for a particular list, but still allow items from another one to be dropped into it? |
Yes, I mean (1) disable sorting for a particular list. But it would also be great, if I could tell a list, that its items don't disappear once they are entering another drop-area (2). In your example above, dragging an item from the left list removes it from this list as soon as it enters the right list. When it is dropped into the right list, it is also recovered in the left list. |
That can definitely be set up, but the behavior around what happens when the item enters into the disabled list isn't very clear. I'm not sure whether the item would be added at the place where the user's cursor entered the new container or whether it would be appended to the list. Either way it might be frustrating for the user if they were trying to put it into a different position. |
Okay, I understand, thanks for your response. Maybe that disable-sorting-feature should require an immutable list, where you can only drag items out of but not into it. According to (2): Do you understand what I mean with that? Or shall I make it more clear? For our project, this is a crucial behavior. |
If I understand it correctly, you want the item to both stay in the original list and show up in the new one? |
Yes :) |
@crisbeto think of it as an 'inventory' container that you only pull items from, for a vizio or lucidchart type app. You may want to sort the inventory but you would probably want to do that from a drag handle, and the drag item that we wish to clone may be inside your sortable container. There should probably be an option for limited or infinite cloning of the drag item as well. I've been thinking of starting a PR for this, but I need some direction. Would you prefer to further configure the If a new directive is preferred, I would also like to submit a sister directive, 'canvas', which will: fix dropped items where they are dropped in the container, account for scroll position, offer snap-to-grid, and scroll-on-hover-edge functionality. If some of the shared functionality was abstracted into a base class, we could start building a library of directives to cover other use cases. I'll submit a new issue for the canvas directive, I just wanted to get your thoughts first since this is your baby. |
@nayfin The canvas idea is interesting. IMO your first paragraph has ideas that the developer should just implement in their component. Tracking how often something has been dragged and sorting should be up to the developer. I'm not sure what you mean by sorting "from a drag handle". Ideally, I think features like scroll-on-hover-edge would be some kind of generic Cdk thing. So you could use it on your canvas when dragging something. But other people could use it for other designs that need scroll-on-edge behavior. This would be more work, but add a lot more utility for developers. |
@arlowhite I agree, unfortunately I don't currently see a way to toggle the sorting feature on the current By sorting from a drag handle I mean that it's likely that you have a list of containers with drag items inside, the items you want to drag clone infinitely but you want to allow the user to sort the list of containers to suit their needs. Heres a quick mock I made using lucidcharts. The up-down arrows represent the sort handles for the container, while the circles are the drag items. This would allow user to sort often used items to the top or wherever they find useful. I know much of this could be executed currently, I don't know how separate drag items will operate inside of a single EDIT: I got most of it working here. It was easier than I expected, kudos to the team. I just need a way to toggle off the sorting/transferring or toggle on a clone mode when I don't want to remove the drag item from the list ondragstart. I still have a lot of work to do making a canvas directive, I'll post progress to a new issue as soon as I have a POC. |
@crisbeto can we please reopen. I don't think there has been a working solution proposed and I am in the middle of two PRs to resolve. |
It really be cool to have this copy behavior, I think it actually solves part of my issue #13796 |
I have a PR ready to merge, that adds a helper function for making copies, similar to the |
…ne array to another (#13743) * feat(drag-utils): add utility function for cloning array items from one array to another creates a utility helper for cloning an array item into the array of the drop container compliments moveItemInArray and transferArrayItem partially closes #13100 * feat(drag-utils): add utility function for cloning array items from one array to another resolves issues surfaced from code review * feat(drag-utils): add utility function for cloning array items from one array to another cuts extra space between parens * removes link in comments, and clarifies function definition as recommended in review * resolves nits
@mmalerba I think this issue is actually two parts: copying an item to a target array in the logic, and adding functionality to tell UI to make a copy of drag item instead of dragging it out of the list then replacing it on drop. Here is a stackblitz highlighting what I described. The function added in #13743 helps with copying the item to the target array but not in addressing requested UI functionality. |
…ne array to another (#13743) * feat(drag-utils): add utility function for cloning array items from one array to another creates a utility helper for cloning an array item into the array of the drop container compliments moveItemInArray and transferArrayItem partially closes #13100 * feat(drag-utils): add utility function for cloning array items from one array to another resolves issues surfaced from code review * feat(drag-utils): add utility function for cloning array items from one array to another cuts extra space between parens * removes link in comments, and clarifies function definition as recommended in review * resolves nits
Hi @nayfin I've seen the pull request and the final result, it looks fine. Thanks |
@TKul6 this discussion probably belongs on the PR, not this issue, but I address those concerns in the comment above yours. #13743 doesn't touch the UI, it's just a helper function to facilitate copying from one array to another. I hope to address the UI in a separate PR as soon as I can find some free time. |
…ne array to another (angular#13743) * feat(drag-utils): add utility function for cloning array items from one array to another creates a utility helper for cloning an array item into the array of the drop container compliments moveItemInArray and transferArrayItem partially closes angular#13100 * feat(drag-utils): add utility function for cloning array items from one array to another resolves issues surfaced from code review * feat(drag-utils): add utility function for cloning array items from one array to another cuts extra space between parens * removes link in comments, and clarifies function definition as recommended in review * resolves nits
I have working solution here. I had to do some strange nesting of drop list containers but it works and supports a limit to the copied items. IMPORTANT: I had to use a list inside a list to pull this off and, styling of the drag items is important. |
Seems cool to me. The But other than that it looks great. Thank you. |
Thanks, I got copy working based on a few suggestions from here. Is there any way to 'disable' the automatic sorting of drop zone items when a dragged item is hovering over them? |
So, I needed to create a toolbox with drag and drop functionality and recently started rewriting the old components we had, removing old and obsolete libraries which were not maintained any longer. I actually found a way to have a (somewhat) proper copy behaviour, it was especially challenging due to the fact that we use placeholders to show the location of the new element. After going through the code, I found that, when using a placeholder, the old element just gets replaced in the HTML nodes, so, my solution basically reverses that. Demo can be found here: What I've got now:
Main things to take in account:
Only final thing I'm encountering now: sometimes there's a very short blinking effect of the placeholder ghost showing, I might be able to get that hidden with some css selectors. I hope this helps anybody else needing copy behaviour |
@Tommatheussen there is work in progress to enable custom drop-zones, these could selectively implement drop list methods and behaviors. See #14261. The issue is still open but looking at the current source, it seems like the required pieces are there. I plan attempting a custom drop-zone in a few weeks after finishing up some other stuff. I'll document if I'm successful and submit a PR to publish so that others can do the same. Then, hopefully we can expand the cdk to facilitate other common drag functionalities. |
That's awesome news, I'll keep an eye out for more details on this. As we have to ship our software in a week or 3, I'll keep my current implementation as is and adapt when it's easier supported on the cdk, thanks for the heads up already :) |
@Tommatheussen Thanks for the example, it really helped. There is an undesirable jitter that occurs when the element it removed and re-added to the DOM (between dragStart and dragMove). I haven't figured out how to get rid of that, it's ugly but not such a major issue. However, the only additional functionality I need is to be able to drag an element outside of its container to remove it. Has anybody figured this out? Even if you drag the element way outside any drop area, cdkDropListDropped still fires with the original container. It would be great if event.container was null if an element was not dropped into any container, but that is not the case. Does anybody have any ideas how to remove the element when it's dragged outside? |
My suggestion for copy behavior would be to use "copyArrayItem" which is similar to "moveArrayItem". For more info see https://material.angular.io/cdk/drag-drop/api#functions |
Any updates on drag and drop copy requirement. |
Like @jayanlee say, this is a stackblitz example with copy https://stackblitz.com/edit/angular-xjex4y |
Yes it copies the items correctly, but the UI is not fitting. In the drag event it pulls the item out of the sourceList and thats not the expected behavior. It will confuse the user. |
JQuery DnD have clone or copy mode, in CDK copy is working but drag preview is creating but the item is not showing in the actual list in UI until drag-drop operations completed. |
You are right @DonsWayo . But i have done a small quick fix for this. dragStart(event:CdkDragStart){ Copy these functions to you ts code. But there is another catch here, the reason why copy functionality is like that because the element that is dragged might not know whether its going to be put in another droplist or same droplist. This quick fix here works only if you put it in another droplist. If you try to put it or swap inside same droplist it creates a redundant name of the draggable element. |
Please provide similar behavior like https://jsfiddle.net/drzaus/mP8kY/ in cdk dnd |
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Bug, feature request, or proposal:
In some designs, you want to drag the same item repeatedly to multiple drop zones. In other words, the drag-and-drop system should support copy behavior as well as move behavior.
What is the expected behavior?
Developers should be able to choose whether a drag and drop acts as a move or a copy. This should be determined by the developer's implementation of the
(dropped)
handler and how they manipulate container data.What is the current behavior?
<cdk-drop>
seems to assume move behavior and has hidden state that prevents the developer from achieving copy behavior. In the(dropped)
handler, if the developer leaves acontainer.data
item in thepreviousContainer
, it can be dragged again as expected. However, on the next drag-and-dropevent.previousIndex = -1
andevent.previousContainer
is the wrongcdk-drop
To clarify:
cdk-drop
source S to A(dropped)
handler, insert the dragged data item into A's data without removing it from S's datacdk-drop
B(dropped)
event hasevent.previousIndex = -1
andevent.previousContainer
iscdk-drop
A instead ofcdk-drop
S.What are the steps to reproduce?
Providing a StackBlitz reproduction is the best way to share your issue.
StackBlitz starter: https://goo.gl/wwnhMV
I can create a demo if needed.
What is the use-case or motivation for changing an existing behavior?
The current
<cdk-drop>
behavior is restrictive and doesn't allow for copy-drag designs.Which versions of Angular, Material, OS, TypeScript, browsers are affected?
Is there anything else we should know?
I worked-around this issue in my App by forcibly re-creating the
<cdk-drop>
within my template (toggle via*ngIf
).Also, in my app, I wanted to be able to drag items from the drop zones back to the source zone as a way of removing them. In this case, I remove the data item from the
previousContainer.data
but nothing in the destination container is changed. Again, I had issues with<cdk-drop>
state and needed to apply my hack of re-generating the component.The text was updated successfully, but these errors were encountered: