diff --git a/src/cdk-experimental/drag-drop/drag.spec.ts b/src/cdk-experimental/drag-drop/drag.spec.ts
index a8cf6b3bc2e..487a684e723 100644
--- a/src/cdk-experimental/drag-drop/drag.spec.ts
+++ b/src/cdk-experimental/drag-drop/drag.spec.ts
@@ -942,6 +942,34 @@ describe('CdkDrag', () => {
});
}));
+ it('should not be able to transfer an item that does not match the `enterPredicate`',
+ fakeAsync(() => {
+ const fixture = createComponent(ConnectedDropZones);
+
+ fixture.detectChanges();
+ fixture.componentInstance.dropInstances.forEach(d => d.enterPredicate = () => false);
+ fixture.detectChanges();
+
+ const groups = fixture.componentInstance.groupedDragItems.slice();
+ const element = groups[0][1].element.nativeElement;
+ const dropInstances = fixture.componentInstance.dropInstances.toArray();
+ const targetRect = groups[1][2].element.nativeElement.getBoundingClientRect();
+
+ dragElementViaMouse(fixture, element, targetRect.left + 1, targetRect.top + 1);
+ flush();
+ fixture.detectChanges();
+
+ const event = fixture.componentInstance.droppedSpy.calls.mostRecent().args[0];
+
+ expect(event).toBeTruthy();
+ expect(event).toEqual({
+ previousIndex: 1,
+ currentIndex: 1,
+ item: groups[0][1],
+ container: dropInstances[0],
+ previousContainer: dropInstances[0]
+ });
+ }));
it('should be able to start dragging after an item has been transferred', fakeAsync(() => {
const fixture = createComponent(ConnectedDropZones);
@@ -1129,7 +1157,7 @@ export class StandaloneDraggableWithMultipleHandles {
{{item}}
`
@@ -1239,7 +1267,7 @@ export class DraggableInDropZoneWithCustomPlaceholder {
[data]="todo"
[connectedTo]="[doneZone]"
(dropped)="droppedSpy($event)">
- {{item}}
+ {{item}}
- {{item}}
+ {{item}}
`
})
diff --git a/src/cdk-experimental/drag-drop/drag.ts b/src/cdk-experimental/drag-drop/drag.ts
index 2c665b866fe..ac4ddad852c 100644
--- a/src/cdk-experimental/drag-drop/drag.ts
+++ b/src/cdk-experimental/drag-drop/drag.ts
@@ -123,7 +123,7 @@ export class CdkDrag implements OnDestroy {
@ContentChild(CdkDragPlaceholder) _placeholderTemplate: CdkDragPlaceholder;
/** Arbitrary data to attach to this drag instance. */
- @Input() data: T;
+ @Input('cdkDragData') data: T;
/** Locks the position of the dragged element along the specified axis. */
@Input('cdkDragLockAxis') lockAxis: 'x' | 'y';
@@ -364,7 +364,7 @@ export class CdkDrag implements OnDestroy {
*/
private _updateActiveDropContainer({x, y}) {
// Drop container that draggable has been moved into.
- const newContainer = this.dropContainer._getSiblingContainerFromPosition(x, y);
+ const newContainer = this.dropContainer._getSiblingContainerFromPosition(this, x, y);
if (newContainer) {
this._ngZone.run(() => {
diff --git a/src/cdk-experimental/drag-drop/drop-container.ts b/src/cdk-experimental/drag-drop/drop-container.ts
index 7030d0684c2..4bbed64e63d 100644
--- a/src/cdk-experimental/drag-drop/drop-container.ts
+++ b/src/cdk-experimental/drag-drop/drop-container.ts
@@ -54,7 +54,7 @@ export interface CdkDropContainer {
getItemIndex(item: CdkDrag): number;
_sortItem(item: CdkDrag, xOffset: number, yOffset: number): void;
_draggables: QueryList;
- _getSiblingContainerFromPosition(x: number, y: number): CdkDropContainer | null;
+ _getSiblingContainerFromPosition(item: CdkDrag, x: number, y: number): CdkDropContainer | null;
}
/**
diff --git a/src/cdk-experimental/drag-drop/drop.ts b/src/cdk-experimental/drag-drop/drop.ts
index d8fcc2c8025..613dc414c71 100644
--- a/src/cdk-experimental/drag-drop/drop.ts
+++ b/src/cdk-experimental/drag-drop/drop.ts
@@ -72,6 +72,12 @@ export class CdkDrop implements OnInit, OnDestroy {
/** Locks the position of the draggable elements inside the container along the specified axis. */
@Input() lockAxis: 'x' | 'y';
+ /**
+ * Function that is used to determine whether an item
+ * is allowed to be moved into a drop container.
+ */
+ @Input() enterPredicate: (drag?: CdkDrag, drop?: CdkDrop) => boolean = () => true;
+
/** Emits when the user drops an item inside the container. */
@Output() dropped: EventEmitter> = new EventEmitter>();
@@ -252,16 +258,17 @@ export class CdkDrop implements OnInit, OnDestroy {
/**
* Figures out whether an item should be moved into a sibling
* drop container, based on its current position.
+ * @param item Drag item that is being moved.
* @param x Position of the item along the X axis.
* @param y Position of the item along the Y axis.
*/
- _getSiblingContainerFromPosition(x: number, y: number): CdkDrop | null {
+ _getSiblingContainerFromPosition(item: CdkDrag, x: number, y: number): CdkDrop | null {
const result = this._positionCache.siblings.find(({clientRect}) => {
const {top, bottom, left, right} = clientRect;
return y >= top && y <= bottom && x >= left && x <= right;
});
- return result ? result.drop : null;
+ return result && result.drop.enterPredicate(item, this) ? result.drop : null;
}
/** Refreshes the position cache of the items and sibling containers. */