In Angular Material CDK Drag Drop, How to Prevent Items from Automatically Rearranging as an Element Moves?
Asked Answered
G

5

9

Thanks in advance. Here's the issue:

I'm using Angular Material CDK Drag Drop (version: @angular/ckd: 7.3.7)

The documentation says "Items will automatically rearrange as an element moves."

My question is: How do I prevent items from automatically rearranging as an element moves?

Here is an animated gif of what I don't want. This is a chess board I made and you can see that the "items (chess pieces) are automatically being rearranged as the element (chess piece) moves"

Here is an animated gif of what I want. What I want is for the items (chess pieces) to not be rearranged as the element (chess piece) moves.

Here is a stackblitz with the code

Gutierrez answered 7/6, 2019 at 18:4 Comment(0)
B
4

Since Angular 8, it's possible to disable this behaviour by adding cdkDropListSortingDisabled

Befit answered 27/4, 2020 at 18:32 Comment(3)
That's an incorrect answer, the items rearrange as well when you try dropping an item. Op expects that the items don't move whatsoever during drop.Woo
This answer answers the question correctly. cdkDropListSortingDisabled prevents element from rearrange in its own scope. In this case sorting = rearrange cuz you change the order of the list. Nevertheless it does not fix the problem when the element is dragged outside the list template area.Cammack
@Cammack what OP wants is currently not so simple as this is multi axis drag&drop that is not natively supported by angular material right now. To workaround this, every element needs to be wrapped by its own container and in that situation angular moves the placeholder between containers.Isometry
W
1

So:

.cdk-drag-placeholder { display:none; } 

Should ensure that the object doesn't get virtually inserted into the DOM restricting this kind of behaviour.

I thought it doesn't work with dynamic lists but apparently .cdk-drag-placeholder { display:none; } does work.

If it doesn't work, that means you are trying to apply the styles on the component and these has been encapsulated within the component to avoid styles leaking. The newly added DOM element doesn't "see" the applied style. A solution would be to put ViewEncapsulation.None so to allow the style to leak from the component and adjust the css rule to something like:

#my-special-list {
    & > .cdk-drag-placeholder {
        display: none !important;
    }
}

So to ensure it doesn't obstruct styles from outside the component.

Woo answered 25/4, 2020 at 21:48 Comment(0)
W
1

just create an empy cdkDragPlaceholder, well, you need enclosed the img in a div

<div class="square"
     [ngClass]="{'white': square.row % 2 === square.col %2,
  'black': square.row % 2 !== square.col % 2}"
  cdkDropList
   ...>
  <div cdkDrag cdkDragBoundary=".board">
    <img *ngIf="square.piece"
       class="piece"
       src="{{square.piece.img()}}"
       />
       <!---this is a empty dragPlaceHolder-->
       <div *cdkDragPlaceholder></div>
   </div>
</div>
Womble answered 30/4, 2020 at 10:55 Comment(0)
K
0

The moving around of items is done by adding an inline style to the elements with a transform: translate3d(Xpx, Ypx, Zpx); rule.

You can overwrite this inline style rule inside your css for the element by setting it to the default zero values add !important. When you do this the rule will not be applied and the rows will stay in place.

/* This prevents cdk drag sorting from shuffling things around */
.piece {
  transform: translate3d(0px, 0px, 0px) !important;
}

I used this trick myself and it works. I tried to make it work in your Stackblitz, but there is too much code and it takes too much time to figure out where exactly to put it. If you want that, you should provide a "minimal working example" not a whole application.

Kossuth answered 5/5, 2021 at 6:57 Comment(0)
I
0

Looks like I found something that might help you.

Add a custom 0px height placeholder to the cdkDrag element. Here: IMAGE

Look at the example below:

<div cdkDrag cdkDragBoundary=".board">
    <img *ngIf="square.piece" class="piece" src="{{ square.piece.img() }}" />
    <div *cdkDragPlaceholder style="height: 0px"></div>
  </div>

Ref: https://stackoverflow.com/a/68121291

Inexcusable answered 23/2, 2023 at 11:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.