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

Add cdk drag-and-drop features #8963

Closed
jelbourn opened this issue Dec 12, 2017 · 94 comments
Closed

Add cdk drag-and-drop features #8963

jelbourn opened this issue Dec 12, 2017 · 94 comments
Assignees
Labels
feature This issue represents a new feature or feature request rather than a bug or bug fix P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent target: minor This PR is targeted for the next minor release
Milestone

Comments

@jelbourn
Copy link
Member

This issue tracks the high-level addition of drag-and-drop features to the cdk.

@jelbourn jelbourn added feature This issue represents a new feature or feature request rather than a bug or bug fix target: minor This PR is targeted for the next minor release labels Dec 12, 2017
@andrewseguin andrewseguin added the P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent label Dec 14, 2017
@fxck
Copy link
Contributor

fxck commented Jan 20, 2018

Is there any design doc I can follow @jelbourn ? I've tried quite a few drag and drop libraries, all of the are bad in one way or another, those that use native APIs are rather limited when it comes to styling the content (which is also often glitched when you drag an item that is partially hidden behind overflow) that is being dragged and those that do it programatically often don't have must have accessibility features like scrolling when the item being dragged is on the side of the scrollable element, so I really wonder how you gonna tackle this.

@jelbourn
Copy link
Member Author

Kristiyan is working on a design now. Any specific feedback you have about what you like/dislike about other libraries would be good to know.

@dojchek
Copy link

dojchek commented Jan 20, 2018

Most of the libs (with native html dnd) such as angular-dnd, sortablejs, dragula handle DOM on their own which is very inconvinient when using unidirectional dataflow (ngrx). There is no an easy way to cancel these updates and walkarounds feel very hacky. This is the biggest issue with all the libs I've used so far
I would love to see the following features:

  • standard drag and drop
  • drag and drop within a list - sortable list
  • support for dnd between different lists - nested/non-nested
  • uniderctional dataflow (option to prevent DOM updates by the lib itself)
  • custom styling of ghost/dragged item
  • support for small devices
  • scroll the droppable container if dragging over the overflow.

Would be awesome if we would get something like https://github.com/atlassian/react-beautiful-dnd

@nayfin
Copy link
Contributor

nayfin commented Jan 23, 2018

Additionally, most seem designed to simply append elements onto lists of other elements when dropped into a drop zone. I would love to see a "canvas" mode implemented to simplify the dropping into an absolute position of an element. This would be extremely useful for design oriented apps, where the user is building something from smaller elements. I used interactjs years ago and really appreciated all it's features ( touch support, inertia, grid snapping, svg support ). It's an older library but could prove useful at least for feature ideas. I'm ready to contribute in any way I can once you all have laid the plans and groundwork.

@Tiedye
Copy link

Tiedye commented Jan 24, 2018

As mentioned dojchek full support for state management like ngrx/redux is very important. We don't yet have an angular dnd library that does.

@jelbourn
Copy link
Member Author

What would be an example of a scenario w/ ngrx interplay with drag-and-drop?

@dallastjames
Copy link

Not sure if this is quite the example you're looking for but I have a site that I maintain that uses drag and drop to create a data sorting functionality. We built it to be closely tied into ngrx where each of the containers (items to be sorted and a container for each category is populated via ngrx store selector. When the user drags an item from one list to another, we cancel all the default drag/drop actions and instead fire a ngrx event that updates the object in question with the new category and let the container selectors "move" the item (this allows for some other things like firing save events and such).

Having something built into the cdk that could facility the drag/drop actions and allow me to intercept at certain events (ie. onDrop) to do things like fire ngrx action and cancel any further drag/drop effects would be great.

@reppners
Copy link

reppners commented Jan 24, 2018

I've ported an angularjs library but intentionally just implemented drop zones to be as general purpose as possible. By having a general purpose drop zone all the ngrx use cases should be possible as well because the library just informs you something has been dropped. What should happen with that event is all up to the developer.

https://github.com/reppners/ngx-drag-drop

So if you're asking for features I'd like to see for CDK than all of what the mentioned library does because it's quite basic (does not do the lists or sorting stuff internally) but configurable to cater all use cases.

Wether it's implemented with native HTML5 drag-and-drop or implementing it all in the angular stack is up to you, but what I'd like to be possible is drag stuff from the outside of the browser into an app. This is just possible with native drag-and-drop.

@angular angular deleted a comment from alvipeo Jan 24, 2018
@benlesh
Copy link
Contributor

benlesh commented Jan 25, 2018

It's probably important to come up with a list of drag, and drag and drop related use cases. What sort of things are we dragging? What sort of drop targets are we going to have? I suspect there's probably more permutations of the latter: single drop targets, groups of drop targets, nested drop targets. There's also a variety of ways that you might want to execute logic when interacting with those targets while dragging or dropping.

ngrx

FWIW, I wouldn't worry about Redux or ngrx when it came to current drag state. That's really a UI concern, and not something I would do as critical to persist to state.

@manju-reddys
Copy link

Interesting library written in ES6 Drag and Drop lib

@Tiedye
Copy link

Tiedye commented Jan 25, 2018

If we could have this: https://github.com/react-dnd/react-dnd for angular, I would be very satisfied.

@samherrmann
Copy link

I am working on drag and drop in an Angular app this week. @dojchek already mentioned most of the features required for my use case, but here are a couple more:

  • support for dynamically adding and removing drop containers
  • support for swappable items
  • support for dnd between a sortable container and a swappable container.
    Example:
    Items in container A are sortable. Items in container B are swappable. If item A1 is dragged over item B1, then item B1 takes the place of item A1, and item A1 can be dropped in the location of item B1. If item B1 is dragged over item A1, then item B1 is inserted into container A either before or after item A1.

@dirkluijk
Copy link
Contributor

dirkluijk commented Feb 1, 2018

Would be great!

On our teams wish list:

  • ghost element features (an element which is appended to the body during the dragging, so it escapes hidden overflows etc). Maybe support providing a ng-template for it?
  • consider multiple positioning strategies? (i.e. you have fixed positioning, absolute positioning, relative positioning, tranforms). Or just pick the best one of these.
  • draggable anchor: a specific element that only triggers the drag start (instead of the whole draggable element).
  • draggable areas: an area that draggable elements cannot escape from.
  • sortable behaviour, but that could become too opiniated quickly.
  • animation possibilities. E.g. ghost element animating back, or animated fitting within dropzone. Maybe this can be done using hooks?
  • scroll behaviour
  • drop behaviour

Another trick/feature is to have the center of the ghost element as reference for the drop behaviour (instead of the pointers position). E.g. you start dragging an element by "grabbing" it at its left side, and when the center of the dragged element covers the dropzone, but your pointer is not hovering it, you still want to be able to drop it in the dropzone?

By the way. When sharing ideas, why not sharing Stackblitzes?
https://draggable-with-anchors-lucas-8eq4ht.stackblitz.io 😄

@dirkluijk
Copy link
Contributor

dirkluijk commented Feb 16, 2018

Today I found some time to work out some ideas. Please see: https://stackblitz.com/edit/draggable-system

What is in it:

  • basic draggable implementation using pointer events
  • draggable positioning 1: positioning the host element (see movable.directive)
  • draggable positioning 2: positioning a helper element (using the CDK)
  • movable area: an area in which elements keep "trapped"
  • sortable behaviour
  • animations (a little bit hacky yet)

The directives:

  • draggable: for emitting the drag events
  • draggable-helper: for showing a helper element (host elements stays in place)
  • movable (extends draggable): element is draggable and will position the host element
  • movable-area: keeps any child movables in its area
  • sortable (extends draggable): element is draggable... nothing more. But is targeted by:
  • sortable-list: keeps track of child sortables and will emit sort events (so user can update its model)

Just wanted to drop my ideas here...

@Tiedye
Copy link

Tiedye commented Feb 16, 2018

@dirkluijk It it supposed to be interactive? I had a look and nothing was draggable, is it supposed to be?

@dirkluijk
Copy link
Contributor

Oops, forgot to add polyfill for pointer events. I guess you checked on a mobile browser. Should work now!

@Tiedye
Copy link

Tiedye commented Feb 17, 2018 via email

@nayfin
Copy link
Contributor

nayfin commented Feb 17, 2018

Firefox worked for me.
@dirkluijk Nice work! That looks better than most Angular drag and drop libraries I have found.
I'm happy to see that we have so many folks chompin' at the bit to contribute to this. I think this project will mature rapidly.

@dirkluijk
Copy link
Contributor

Here is a second version with some droppable ideas demonstrated: https://stackblitz.com/edit/draggable-system-2

  • droppable (extends draggable, to keep things separated from the base directive):
    • An additional draggableData can be set which will be included in the custom events emitted.
    • A "dragGroup" can be set to identify separate drag/drop groups.
  • drop-zone: detects when droppables are dropped inside its host element.
    • "dragGroups" can be set to accept only specific groups of droppables.

@Tiedye
Copy link

Tiedye commented Feb 18, 2018

@dirkluijk looks like the polyfill you added didn't stick, it works great when I do add the polyfill though!

@dirkluijk
Copy link
Contributor

@Tiedye My mistake. Updated both Stackblitz demos!

@FDIM
Copy link

FDIM commented Feb 19, 2018

I didn't see this one mentioned anywhere: http://kamilkp.github.io/angular-sortable-view/

Few forks down it works ok for our use cases - I had to implement auto scrolling on any number of scroll-able parents though and fix it on mobile on latest chrome (thanks to passive flag). It is also working nicely in IE 11. On the other hand the version we have in the project is cleaned up a bit more and I think I could make it public if it would help anyone.

Sadly it's only available for angularjs and doesn't seem to be maintained. Maybe some ideas / code could still be reused? It is fully declarative after all.
That aside, I have to find / make an alternative as well as we are in the process of migrating. Personally I'd would try to rewrite that - as others outlined, there aren't that many good ones out there.

@fxck
Copy link
Contributor

fxck commented Feb 19, 2018

I think it would be a good idea to wait and see what @crisbeto has in store, how far in development / design process he is.

@crisbeto
Copy link
Member

@BirdInTheCity yes, it would be useful to have a ticket for it.

@BirdInTheCity
Copy link

@crisbeto Posted the bug. Includes animated gif to help explain. Take a look. Thanks!

@intellix
Copy link

Was trying to use cdkDrag earlier and getting griefed a fair bit. After making a minimal reproduction in StackBlitz I realised that the textarea element within cdkDrag causes issues along with cdkDragHandler: #12718

Reproduction: https://stackblitz.com/edit/angular-3h4hbb?file=src%2Fapp%2Fapp.component.html

@cormacrelf
Copy link

cormacrelf commented Aug 18, 2018

To @Tiedye and others — as @thefliik noted above, I built the react-dnd implementation, angular-skyhook. It works very well with NgRx. There are a number of examples using it on the demo site, including a clone of the macOS calendar.

I see that Cdk is targeting a sortable, and angular-skyhook is much more general purpose than that, but I am working on a sortable implementation on top — if anyone has any input on the API design or wants to contribute, it would be very welcome over at cormacrelf/angular-skyhook#69.

(Also, @crisbeto, I read the comments about change detection on fast-moving values — you may find some of the core angular-skyhook code interesting. I used a separate zone for all code, that comes back to Angular when users opt into events they’re interested in (‘interested’ = distinctUntilChanged on the listen() observable, or a spec method is provided). Observables can even be scheduled to have CD run after they are processed. It works optimally, even as a blanket rule.)

mmalerba pushed a commit that referenced this issue Aug 20, 2018
This is something that came up during a discussion in #8963. Adds the `cdkDragMoved` event which will emit as an item is being dragged. Also adds some extra precautions to make sure that we're not doing extra work unless the consumer opted into the event.
IlCallo pushed a commit to IlCallo/material2 that referenced this issue Aug 23, 2018
This is something that came up during a discussion in angular#8963. Adds the `cdkDragMoved` event which will emit as an item is being dragged. Also adds some extra precautions to make sure that we're not doing extra work unless the consumer opted into the event.
@ganeshkbhat
Copy link

A nice place to get started I found this on google. https://github.com/misha130/ngx-drag-and-drop-lists

@jelbourn jelbourn added this to the 7.0 milestone Aug 29, 2018
@ptoro
Copy link

ptoro commented Sep 15, 2018

Really the drag and drop feature addition.

However I noticed a problem where input elements such as buttons, text fields, and checkboxes don't receive click events. All clicks on a CdkDrag element seem to be fire a CdkDragDrop event but no click event. Is the CdkDragDrop event consuming the click and preventing the click from passing through to the input element?

Has anyone been able to get a button working in a CdkDrag element?

Here's a stackblitz with the minimum code necessary to reproduce the issue: https://angular-qpqmw8.stackblitz.io

Let me know if it'd help to create an issue for this.

@nayfin
Copy link
Contributor

nayfin commented Sep 17, 2018

@ptoro seems like you would want a drag handle on any of those elements if you'd like to drag them. I can see how it would be useful for a form builder or something similar but you'd remove the cdkDrag directive after form is built and button would act like a traditional button. It feels like you are overloading these elements, but I might be missing something.

@ptoro
Copy link

ptoro commented Sep 18, 2018

@nayfin

seems like you would want a drag handle on any of those elements if you'd like to drag them.

Not necessarily. For example, think of an image gallery where you might want to be able to drag a picture to reorder it but also click to enlarge it. It's not just an image gallery though. It's true any time you have an element itself you want to grab hold of to drag but also click.

Even regardless of individual use cases, a drag and drop library should not consume all ClickEvents as all ClickEvents are not drag and drop events and should be available for consumption by the developer.

Dragula (ng2-dragula) does a good job implementing this: https://valor-software.com/ng2-dragula/index.html (scroll to the section "Click or Drag!").

@crisbeto
Copy link
Member

@ptoro @nayfin we had a TODO to avoid interfering with click events. It'll be resolved by #13152.

@ptoro
Copy link

ptoro commented Sep 19, 2018

Thanks for creating that PR @crisbeto.

Playing around with the feature a bit more, I ran into another problem. If you want to only allow one-way dragging (e.g. left list to right list), you remove the connectedTo directive from one of the lists. This causes a problem where if you drag from one list to another list and back to the original list without dropping, the cdkDrag element you dragged won't go back to the original list. Here's a gif that showcases this behavior: cdk drag-drop one-way drag issue reprodution

I can provide a StackBiltz but the only change I had to make from this StackBlitz for the Transferring items between lists example to reproduce this behavior was to remove [connectedTo]="[todoList]" from the donelist's cdkDrop selector. (Side note: I had to copy the StackBlitz code and run it locally because none of the StackBiltzs linked to on this page are working. They either won't drag or it shows an error. I didn't notice anyone else mention this or an existing issue for it.)

Happy to create an issue for this if necessary.

@crisbeto
Copy link
Member

crisbeto commented Sep 20, 2018

Thanks for the report @ptoro, could you file your exact comment as an issue? I'm closing down this issue since the drag&drop is close to being released in stable and having issues in here makes them hard to track over time.

@narendrasinghrathore
Copy link

narendrasinghrathore commented Oct 17, 2018

Can't resolve '@angular/cdk/drag-drop'

image

https://beta-angular-material-io.firebaseapp.com/cdk/drag-drop/api#directives

unable to resolve the dependency .

Any help ? @crisbeto

@nayfin
Copy link
Contributor

nayfin commented Oct 17, 2018

Try @angular/cdk/drag-drop/experimentalif you're on v6, drop experimental if you're on v7 beta

@narendrasinghrathore
Copy link

@nayfin Didn't seem folder is here.
I am using v6.
image

@nayfin
Copy link
Contributor

nayfin commented Oct 17, 2018

Sorry, you also need @angular/cdk-experimental: 6.4.7 in your package.json dependencies. Here's a link to a stackblitz highlighting how to connect drop zones across templates, that should help if you're still stuck.
It will be a little more straightforward once v7 drops.

@narendrasinghrathore
Copy link

@nayfin
Package "@angular/cdk-experimental" was found but does not support schematics
ng add @angular/cdk-experimental@6.4.7

Is something wrong here ?

"dependencies": { "@angular/animations": "^6.1.10", "@angular/cdk": "^6.4.7", "@angular/cdk-experimental": "^6.4.7", "@angular/common": "^6.1.0", "@angular/compiler": "^6.1.0", "@angular/core": "^6.1.0", "@angular/forms": "^6.1.0", "@angular/http": "^6.1.0", "@angular/material": "^6.4.7", "@angular/platform-browser": "^6.1.0", "@angular/platform-browser-dynamic": "^6.1.0", "@angular/router": "^6.1.0", "core-js": "^2.5.4", "hammerjs": "^2.0.8", "rxjs": "^6.0.0", "zone.js": "~0.8.26" }, "devDependencies": { "@angular-devkit/build-angular": "~0.7.0", "@angular/cli": "~6.1.5", "@angular/compiler-cli": "^6.1.0", "@angular/language-service": "^6.1.0", "@types/jasmine": "~2.8.6", "@types/jasminewd2": "~2.0.3", "@types/node": "~8.9.4", "codelyzer": "~4.2.1", "jasmine-core": "~2.99.1", "jasmine-spec-reporter": "~4.2.1", "karma": "~1.7.1", "karma-chrome-launcher": "~2.2.0", "karma-coverage-istanbul-reporter": "~2.0.0", "karma-jasmine": "~1.1.1", "karma-jasmine-html-reporter": "^0.2.2", "protractor": "~5.4.0", "ts-node": "~5.0.1", "tslint": "~5.9.1", "typescript": "~2.7.2" }

@nayfin
Copy link
Contributor

nayfin commented Oct 17, 2018

I doubt there is a schematic for it. Just add to dependencies and npm install. Are you getting an error?

@narendrasinghrathore
Copy link

narendrasinghrathore commented Oct 17, 2018

@nayfin Did npm install
`npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.4 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.4: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

up to date in 30.943s
`
Seems to work
But some issue, following this example https://run.stackblitz.com/api/angular/v1?file=app%2Fcdk-drag-drop-sorting-example.ts

image

@nayfin
Copy link
Contributor

nayfin commented Oct 17, 2018

Those are just warnings telling you that you're using Windows

@narendrasinghrathore
Copy link

@nayfin Any idea why such behaviour
2018-10-17_22-10-10

@pas2al
Copy link
Contributor

pas2al commented Oct 17, 2018

Would you mind to move your support questions over to StackOverflow or Gitter? Everyone who follows this issue gets notified. The Angular team kindly asks to keep issues clean for bugs etc.

Please do not open issues for general support questions as we want to keep GitHub issues for bug reports and feature requests. You've got much better chances of getting your question answered on StackOverflow where the questions should be tagged with tag angular-material2.

Thanks <3

@narendrasinghrathore
Copy link

@pas2al My bad,

Regards.

@narendrasinghrathore
Copy link

@nallwhy Just for update
I used version: 7.0.0-rc.1
ng add @angular/cdk@7.0.0-rc.1

Is working as expected.

Thanks
2018-10-17_22-22-37

@jelbourn
Copy link
Member Author

jelbourn commented Oct 17, 2018

Locking this thread since it's gone off-topic now. Drag-and-drop is being released as part of Angular v7. Feel free to open new issues for bug reports.

@angular angular locked as off-topic and limited conversation to collaborators Oct 17, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feature This issue represents a new feature or feature request rather than a bug or bug fix P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent target: minor This PR is targeted for the next minor release
Projects
None yet
Development

No branches or pull requests