I´m working in a application implementing the new drag and drop from angular material CDK and i´m trying to cancel the drag event of the element pressing Esc
, i mean, i start dragging the element but if i press Esc
while i´m dragging the element, it should go back to the position from where i start dragging it, so far i haven´t found a way to do this, does anyone know how can i do this. There nothing in the cdk documentation about this any idea. i try doing something like this.
Template
<div cdkDropList class="example-list" (cdkDropListDropped)="drop($event)">
<div class="example-box" *ngFor="let movie of movies" (cdkDragEnded)="onDragEnded($event)" cdkDrag>{{movie}}</div>
</div>
Ts component
onDragEnded(event: CdkDragEnd) {
console.log(event)
event.source.element.nativeElement.style.transform = 'none';
const source: any = event.source;
source._passiveTransform = { x: 0, y: 0 };
}
but no success so far.
I´m working in a application implementing the new drag and drop from angular material CDK and i´m trying to cancel the drag event of the element pressing Esc
, i mean, i start dragging the element but if i press Esc
while i´m dragging the element, it should go back to the position from where i start dragging it, so far i haven´t found a way to do this, does anyone know how can i do this. There nothing in the cdk documentation about this any idea. i try doing something like this.
Template
<div cdkDropList class="example-list" (cdkDropListDropped)="drop($event)">
<div class="example-box" *ngFor="let movie of movies" (cdkDragEnded)="onDragEnded($event)" cdkDrag>{{movie}}</div>
</div>
Ts component
onDragEnded(event: CdkDragEnd) {
console.log(event)
event.source.element.nativeElement.style.transform = 'none';
const source: any = event.source;
source._passiveTransform = { x: 0, y: 0 };
}
but no success so far.
Share Improve this question asked Dec 4, 2018 at 9:05 Miguel FriasMiguel Frias 2,7108 gold badges34 silver badges55 bronze badges 3 |5 Answers
Reset to default 10I also faced this problem for a long time. Finally I could fix it by dispatching a mouseup
event that will act as the user releasing the mouse.
@HostListener('window:keyup', ['$event'])
handleKeyboardEvent(event: KeyboardEvent) {
if (event.key === 'Escape') {
document.dispatchEvent(new Event('mouseup'));
}
}
This is an extremely hacky solution and comes with it's down sides. In fact, you are not cancelling the drag but instead dropping. Meaning that if you are hovering a cdkDropList
or one is active it will trigger the cdkDropListDropped
emmiter for that list. Something you can easily workaround by adding a flag.
private _canceledByEsq = false;
@HostListener('window:keyup', ['$event'])
handleKeyboardEvent(event: KeyboardEvent) {
if (event.key === 'Escape') {
this._canceledByEsq = true;
document.dispatchEvent(new Event('mouseup'));
}
}
handleDrop() {
if (!this._canceledByEsq) {
// Do my data manipulations
}
}
Hope this helps you... :)
You can move the dragged item to a position using:
event['source']['element']['nativeElement']['style']['transform'] = 'translate3d(0,0,0)';
event['source']['_dragRef']['_activeTransform'] = {x: 0, y: 0};
event['source']['_dragRef']['_passiveTransform'] = {x: 0, y: 0};
The best way to do it is to call event.source._dragRef.reset();
(as @AleRubis mentioned in comment) on ESC
key press.
Now the question is from where you can get that _dragRef outside cdkDrag events (ESC
key event), you can save it in a component variable like this when drag starts.
Component:
cdkDragStarted = (event) => {
this.dragRef = event.source._dragRef;
}
Template:
<p cdkDrag (cdkDragStarted)="cdkDragStarted($event)">
Draggable paragraph
</p>
Here's a version using rxjs. It requires a reference to CdkDrag
as ViewChild. Unfortunately, because there is no public method to stop dragging on the DragRef
you have to use dispatchEvent
as the only way to end the dragging process.
There are two parts in the example below. What's happening is that the ended event can only be listened to after a start, and that instance of listening can be stopped by a subject triggered by pressing escape.
- In the AfterViewInit a subscription is created to the started EventEmitter from the
CdkDrag
directive. - After the start event, the stream that switches to listening to ended.
- If the cancel request is fired, the stream will be ended by the
takeUntil
operator, andreset()
will be called on the directive to reset the position anddispatchEvent()
will be used to stop the drag process. - Otherwise once the end event is fired, the
onDragEnded()
method is called from the OP. - Unless there is some really funniness going on, the ended event will only be fired at most once per start, so there is no need for an additional
take(1)
.
private dragCancelRequest = new Subject();
ngAfterViewInit() {
this.drag.started.pipe(
switchMap(({ source }) => source.ended.pipe(
takeUntil(this.dragCancelRequest.pipe(tap(() => {
source.reset();
document.dispatchEvent(new Event('mouseup'));
})))
)),
tap(x => this.onDragEnded(x))
).subscribe();
}
@HostListener('window:keyup', ['$event'])
handleKeyboardEvent(event: KeyboardEvent) {
if (event.key === 'Escape') {
this.dragCancelRequest.next();
}
}
You can use something like...
@HostListener('window:keyup', ['$event'])
handleKeyboardEvent(event: KeyboardEvent) {
if (event.code === 'Escape') {
// call dragend event
}
}
source._passiveTransform
you can now doevent.source._dragRef.reset();
– AleRubis Commented Jun 13, 2019 at 8:23