Skip to content

Commit ec9693c

Browse files
committed
feat(drag-n-drop): fixed drag-from-outside example, plus some bugs when we have multiple grids
1 parent 3d38c81 commit ec9693c

File tree

5 files changed

+68
-50
lines changed

5 files changed

+68
-50
lines changed

projects/angular-grid-layout/src/lib/grid.component.ts

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ import {KtdDrag} from "./directives/ktd-drag";
5353
// region Types
5454

5555
interface KtdGridDrag {
56-
dragSubscription: Subscription;
57-
scrollSubscription: Subscription;
56+
dragSubscription: Subscription | null;
57+
scrollSubscription: Subscription | null;
5858
startEvent: MouseEvent | TouchEvent;
5959
newLayout: Layout | null;
6060
newLayoutItem: LayoutItem | null;
@@ -70,18 +70,17 @@ export type KtdDragStart = KtdDragResizeEvent;
7070
export type KtdDragEnter = KtdGridEnterLeaveEvent;
7171
export type KtdDragLeave = KtdGridEnterLeaveEvent;
7272
export type KtdDragEnd = KtdDragResizeEvent;
73-
export type KtdDropped = KtdDroppedEvent;
73+
export type KtdDropped<T = any> = KtdDroppedEvent<T>;
7474

7575
export type KtdResizeStart = KtdDragResizeEvent;
7676
export type KtdResizeEnd = KtdDragResizeEvent;
7777

78-
interface KtdDroppedEvent {
78+
interface KtdDroppedEvent<T> {
7979
event: PointingDeviceEvent;
8080
previousLayout: KtdGridLayout | null; // Previous layout is null only when dragging ktdDrag
8181
currentLayout: KtdGridLayout;
82-
previousLayoutItem: KtdGridLayoutItem | null; // Previous layout is null only when dragging ktdDrag
83-
currentLayoutItem: KtdGridLayoutItem;
84-
data: any;
82+
previousLayoutItem: KtdGridLayoutItem<T> | null; // Previous layout is null only when dragging ktdDrag
83+
currentLayoutItem: KtdGridLayoutItem<T>;
8584
}
8685

8786
export interface KtdGridItemResizeEvent {
@@ -607,6 +606,7 @@ export class KtdGridComponent implements OnChanges, AfterContentInit, AfterConte
607606
h: 1,
608607
x: -1,
609608
y: -1,
609+
data: dragInfo.dragRef.data,
610610
} : null,
611611
};
612612
}
@@ -620,8 +620,10 @@ export class KtdGridComponent implements OnChanges, AfterContentInit, AfterConte
620620

621621
if (this.drag != null) {
622622
this.destroyPlaceholder();
623-
this.drag.dragSubscription.unsubscribe();
624-
this.drag.scrollSubscription.unsubscribe();
623+
this.drag.dragSubscription?.unsubscribe();
624+
this.drag.scrollSubscription?.unsubscribe();
625+
this.drag.dragSubscription = null;
626+
this.drag.scrollSubscription = null;
625627
}
626628
}
627629

@@ -766,7 +768,7 @@ export class KtdGridComponent implements OnChanges, AfterContentInit, AfterConte
766768
this.addGridItemAnimatingClass(dragInfo.dragRef).subscribe();
767769
// Consider destroying the placeholder after the animation has finished.
768770
this.destroyPlaceholder();
769-
this.drag.dragSubscription.unsubscribe();
771+
this.drag.dragSubscription?.unsubscribe();
770772
this.drag.scrollSubscription?.unsubscribe();
771773
this.drag = null;
772774
}
@@ -778,24 +780,34 @@ export class KtdGridComponent implements OnChanges, AfterContentInit, AfterConte
778780

779781
// Add new item to the layout if it is being dragged from outside the grid.
780782
this.ngZone.run(() => {
781-
this.dropped.emit({
782-
event: dragInfo.moveEvent,
783-
previousLayout: dragInfo.fromGrid !== null ? dragInfo.fromGrid.layout : null,
784-
currentLayout: this.drag!.newLayout!.map(item => ({
785-
id: item.id,
786-
x: item.x,
787-
y: item.y,
788-
w: item.w,
789-
h: item.h,
790-
minW: item.minW,
791-
minH: item.minH,
792-
maxW: item.maxW,
793-
maxH: item.maxH,
794-
})) as KtdGridLayout,
795-
previousLayoutItem: previousLayoutItem !== undefined ? previousLayoutItem : null,
796-
currentLayoutItem: currentLayoutItem !== undefined ? currentLayoutItem : {...this.drag!.newLayoutItem!, id: this.getNextId()},
797-
data: dragInfo.dragRef.data,
798-
});
783+
// Do not emit when:
784+
// - Drag is a resize and bounds have not changed.
785+
// - Drag is a normal drag and the item is being dragged inside the same grid.
786+
// - We are dragging from outside the grid and the item was dragged into the grid, but then pointer was released outside the grid.
787+
if (dragInfo.type !== 'resize' && this.drag!.newLayoutItem !== null && dragInfo.currentGrid === this) {
788+
this.dropped.emit({
789+
event: dragInfo.moveEvent,
790+
previousLayout: dragInfo.fromGrid !== null ? dragInfo.fromGrid.layout : null,
791+
currentLayout: this.drag!.newLayout!.map(item => ({
792+
id: item.id,
793+
x: item.x,
794+
y: item.y,
795+
w: item.w,
796+
h: item.h,
797+
minW: item.minW,
798+
minH: item.minH,
799+
maxW: item.maxW,
800+
maxH: item.maxH,
801+
data: item.data,
802+
})) as KtdGridLayout,
803+
previousLayoutItem: previousLayoutItem !== undefined ? previousLayoutItem : null,
804+
currentLayoutItem: currentLayoutItem !== undefined ? currentLayoutItem : {...this.drag!.newLayoutItem!, id: this.getNextId()},
805+
});
806+
return;
807+
}
808+
809+
// Emit when we are not dragging or resizing items already inside the grid.
810+
this.layoutUpdated.emit(this.drag!.newLayout!);
799811
});
800812
}
801813
}

projects/angular-grid-layout/src/lib/grid.definitions.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { CompactType } from './utils/react-grid-layout.utils';
33
import { KtdClientRect } from './utils/client-rect';
44

55

6-
export interface KtdGridLayoutItem {
6+
export interface KtdGridLayoutItem<T = any> {
77
id: string;
88
x: number;
99
y: number;
@@ -13,6 +13,7 @@ export interface KtdGridLayoutItem {
1313
minH?: number;
1414
maxW?: number;
1515
maxH?: number;
16+
data?: T;
1617
}
1718

1819
export type KtdGridCompactType = CompactType;

projects/angular-grid-layout/src/lib/utils/react-grid-layout.utils.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export type LayoutItem = {
2020
static?: boolean;
2121
isDraggable?: boolean | null | undefined;
2222
isResizable?: boolean | null | undefined;
23+
data?: any;
2324
};
2425
export type Layout = Array<LayoutItem>;
2526
export type Position = {
@@ -117,6 +118,7 @@ export function cloneLayoutItem(layoutItem: LayoutItem): LayoutItem {
117118
if (layoutItem.minH !== undefined) { clonedLayoutItem.minH = layoutItem.minH;}
118119
if (layoutItem.maxH !== undefined) { clonedLayoutItem.maxH = layoutItem.maxH;}
119120
// These can be null
121+
if (layoutItem.data !== undefined) { clonedLayoutItem.data = layoutItem.data;}
120122
if (layoutItem.isDraggable !== undefined) { clonedLayoutItem.isDraggable = layoutItem.isDraggable;}
121123
if (layoutItem.isResizable !== undefined) { clonedLayoutItem.isResizable = layoutItem.isResizable;}
122124

projects/demo-app/src/app/drag-from-outside/drag-from-outside.component.html

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
<div class="pokemons-container">
3-
<div *ngFor="let pokemon of pokemonsGen1; let i = index" ktdDrag [connectedTo]="[gridLeft, gridRight]" [width]="1" [id]="pokemon.name" class="pokemon-drag-item">
4-
<img [src]="pokemonsGen1Dict[pokemon.name].img">
3+
<div *ngFor="let pokemon of pokemonsGen1Dict; let i = index" ktdDrag [ktdDragData]="pokemon" [connectedTo]="[gridLeft, gridRight]" [width]="1" class="pokemon-drag-item">
4+
<img [src]="pokemon.img">
55
{{pokemon.name}}
66
</div>
77
</div>
@@ -18,15 +18,17 @@
1818
[layout]="layout"
1919
[scrollableParent]="document"
2020
(dropped)="onLayoutDropped($event)"
21-
(layoutUpdated)="onLayoutUpdated($event)">
21+
(layoutUpdated)="onLayoutUpdated($event)"
22+
>
2223
<ktd-grid-item *ngFor="let item of layout; trackBy:trackById"
2324
draggable="true"
2425
resizable="true"
2526
dragStartThreshold="0"
2627
[id]="item.id">
27-
{{item.id}} {{pokemonsGen1Dict[item.id] | json}}
28-
<img [src]="pokemonsGen1Dict[item.id].img">
29-
{{pokemonsGen1Dict[item.id].name}}
28+
<div class="pokemon-drag-item">
29+
<img [src]="item.data.img">
30+
<a [href]="item.data.url" target="_blank">{{item.data.name}}</a>
31+
</div>
3032
</ktd-grid-item>
3133
</ktd-grid>
3234

@@ -50,9 +52,10 @@
5052
resizable="true"
5153
dragStartThreshold="0"
5254
[id]="item.id">
53-
54-
<img [src]="pokemonsGen1Dict[item.id].img">
55-
{{pokemonsGen1Dict[item.id].name}}
55+
<div class="pokemon-drag-item">
56+
<img [src]="item.data.img">
57+
<a [href]="item.data.url" target="_blank">{{item.data.name}}</a>
58+
</div>
5659
</ktd-grid-item>
5760
</ktd-grid>
5861
</div>

projects/demo-app/src/app/drag-from-outside/drag-from-outside.component.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,15 @@ import { CommonModule, DOCUMENT } from '@angular/common';
66
import { RouterModule } from '@angular/router';
77
import { KtdFooterComponent } from '../components/footer/footer.component';
88
import { pokemonsGen1 } from './pokemons-gen1';
9-
import { KtdDictionary } from '../types';
109
import {compact} from "../../../../angular-grid-layout/src/lib/utils/react-grid-layout.utils";
1110
import {KtdDropped} from "../../../../angular-grid-layout/src/lib/grid.component";
1211

12+
13+
interface Pokemon {
14+
name: string,
15+
url: string,
16+
img: string
17+
}
1318
@Component({
1419
selector: 'ktd-drag-from-outside',
1520
standalone: true,
@@ -25,15 +30,10 @@ export class KtdDragFromOutsideComponent implements OnInit, OnDestroy {
2530
compactType: KtdGridCompactType = null;
2631
backgroundConfig: KtdGridBackgroundCfg = {show: 'always'};
2732

28-
pokemonsGen1 = pokemonsGen1;
29-
30-
pokemonsGen1Dict: KtdDictionary<{ name: string, url: string, img: string }> = pokemonsGen1.reduce((acc, cur, index) => ({
31-
...acc,
32-
[cur.name as string]: {
33-
...cur,
34-
img: `https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/${index + 1}.png`
35-
}
36-
}), {})
33+
pokemonsGen1Dict: Pokemon[] = pokemonsGen1.map((pokemon, index) => ({
34+
...pokemon,
35+
img: `https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/${index + 1}.png`
36+
}));
3737

3838
private resizeSubscription: Subscription;
3939

@@ -59,7 +59,7 @@ export class KtdDragFromOutsideComponent implements OnInit, OnDestroy {
5959
this.layout = layout;
6060
}
6161

62-
onLayoutDropped(event: KtdDropped) {
62+
onLayoutDropped(event: KtdDropped<Pokemon>) {
6363
console.log('onLayoutDropped', event);
6464
this.layout = [event.currentLayoutItem, ...event.currentLayout];
6565
this.layout = compact(this.layout, this.compactType, this.grid.cols);
@@ -70,7 +70,7 @@ export class KtdDragFromOutsideComponent implements OnInit, OnDestroy {
7070
this.layout2 = layout;
7171
}
7272

73-
onLayout2Dropped(event: KtdDropped) {
73+
onLayout2Dropped(event: KtdDropped<Pokemon>) {
7474
console.log('onLayoutDropped', event);
7575
this.layout2 = [event.currentLayoutItem, ...event.currentLayout];
7676
this.layout2 = compact(this.layout2, this.compactType, this.grid.cols);

0 commit comments

Comments
 (0)