Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a mat-table row drag-drop work with cdkDragHandle so that the row is only draggable using the handle?

I found this stackblitz example of adding drag-drop to a mat-table using angular cdk. However, the desired behavior is that the row is only draggable using the element with the cdkDragHandle directive. In this example you can drag the element by clicking anywhere on the row. How can this be modified so that the row is only draggable using the drag handle?

https://stackblitz.com/edit/angular-igmugp

like image 802
phelhe Avatar asked Mar 06 '19 16:03

phelhe


People also ask

How do you drag and drop CDK?

When you check in the browser, it allows you to drag the item. It will not drop it in the list and will remain as it is when you leave the mouse pointer. The function onDrop takes care of dropping the item dragged in the position required.

How do I turn off drag and drop on CDK?

If you want to disable dragging for a particular drag item, you can do so by setting the cdkDragDisabled input on a cdkDrag item. Furthermore, you can disable an entire list using the cdkDropListDisabled input on a cdkDropList or a particular handle via cdkDragHandleDisabled on cdkDragHandle .

How do you drag and drop in angular 6?

To implement drag and drop list you have to include your ngFor repeated section inside a parent div to make that section draggable. This is just a basic structure of how the draggable section should look. Now we have to provide DndList directives to this structure. Basic functioning HTML for drag and drop list.

How to implement drag and drop on a mat-table?

For anyone wondering how to implement drag and drop on a mat-table, you need to: on ListDrop (event: CdkDragDrop<string[]>) { // Swap the elements around move ItemInArray (this.myArray, event.previousIndex, event.currentIndex) ; } moveItemInArray is an Angular Material function.

Is it possible to make the row only draggable using the drag handle?

However, the desired behavior is that the row is only draggable using the element with the cdkDragHandle directive. In this example you can drag the element by clicking anywhere on the row. How can this be modified so that the row is only draggable using the drag handle? Show activity on this post.

Does CDK drag and drop work with material table?

I heard the cdk drag and drop work well with Material table. Because in material table, you can use the flexbox implementation.

How do I add drag and drop functionality to a table?

...] To add drag and drop functionality we must define the table as a cdkDropList and the rows as cdkDrag. The cdkDropList is a container that, when wrapped around cdkDrag elements, groups the drag elements into a reorderable list.


3 Answers

Here is my workaround for this issue:

  1. Make a boolean to control whether cdkDrag should be disabled. Default behavior is disabled.
  2. Add a mousedown, mouseup, touchstart, and touchend event handler to the cdkDragHandle to toggle the control.
  3. In the cdkDrag, listen to the cdkDragReleased event to disable the cdkDrag after it is dragged.

The side-effect is that it becomes harder to work with items that you really want to disable (e.g. apply style for those truly disabled items).

The code looks like below:

  • Component class
  dragDisabled = true;
  • cdkDrag
<mat-row
  *matRowDef="let row; columns: displayedColumns"
  cdkDrag
  [cdkDragData]="row"
  [cdkDragDisabled]="dragDisabled"
  (cdkDragReleased)="dragDisabled = true"
></mat-row>
  • cdkDragHandle
<mat-icon
  cdkDragHandle
  (touchstart)="dragDisabled = false"
  (touchend)="dragDisabled = true"
  (mousedown)="dragDisabled = false"
  (mouseup)="dragDisabled = true"
  >drag_indicator</mat-icon
>
like image 184
Avin Shum Avatar answered Oct 14 '22 01:10

Avin Shum


I have found a somewhat simple issue to this complex problem. For any simple text td in the draggable tr, we can use the pointer-events:none and it will disable all the text element.

On the handle icon, use the pointer-events:all and it will enable dragging from only the icon.

This also has the issue where it disables all the anchor and buttons. So for icon and buttons do the follwoing

  1. using mouseDown set a flag
  2. on drag start, check the drag and throw mouseup event
  3. on drag stop, check if flag is set and reset flag and return

check this stackblits for working answer https://stackblitz.com/edit/angular-rwzc76

like image 27
Mamoon ur Rasheed Avatar answered Oct 14 '22 01:10

Mamoon ur Rasheed


IMHO there is no quick-fix to this, other than hacking/overriding the source code of Angular Material / CDK. Testament of this is the open feature request at github: https://github.com/angular/material2/issues/13770.

The issue is that the cdkDrag on a datasource / MatTable automatically creates drag annotations on all child elements (which generates the behavior) and can't be (easily) overriden.

Based on the documentation cdkDrag/cdkDragDisabled - cdkDragHandle/cdkDragHandleDisabled should help (it does work without a table). I've upgraded all the libraries from the example to support them but to no effect.

like image 2
jcuypers Avatar answered Oct 14 '22 01:10

jcuypers