Skip to content

Commit d573411

Browse files
fix(platform): disable scrolling during table row drag and drop (#13343)
* fix(platform): disable scrolling during table row drag and drop * fix(platform): call function to re-enable dragging after drop --------- Co-authored-by: deno <[email protected]>
1 parent b5f40a4 commit d573411

File tree

5 files changed

+85
-9
lines changed

5 files changed

+85
-9
lines changed

libs/cdk/src/lib/utils/directives/focusable-grid/focusable-grid.directive.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ export class FocusableGridDirective implements AfterViewInit {
6262
@ContentChildren(FDK_FOCUSABLE_LIST_DIRECTIVE, { descendants: true })
6363
private readonly _focusableLists: QueryList<FocusableListDirective>;
6464

65+
/** @hidden */
66+
_preventKeydown = false;
67+
6568
/** @hidden */
6669
constructor(private readonly _destroy$: DestroyedService) {}
6770

@@ -129,7 +132,10 @@ export class FocusableGridDirective implements AfterViewInit {
129132

130133
/** @hidden */
131134
_onKeydown(event: KeyboardEvent, list: FocusableListDirective, activeItemIndex: Nullable<number>): void {
132-
if (!KeyUtil.isKeyCode(event, [UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW, PAGE_DOWN, PAGE_UP])) {
135+
if (
136+
!KeyUtil.isKeyCode(event, [UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW, PAGE_DOWN, PAGE_UP]) ||
137+
this._preventKeydown
138+
) {
133139
return;
134140
}
135141

libs/platform/src/lib/table-helpers/directives/table-draggable.directive.ts

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,16 @@ import {
88
inject,
99
Input,
1010
NgZone,
11+
OnDestroy,
1112
Output
1213
} from '@angular/core';
1314
import {
1415
DragoverPredicate,
1516
DropPredicate,
1617
FdDndDropEventMode,
1718
FdDndDropType,
18-
FdDropEvent
19+
FdDropEvent,
20+
KeyUtil
1921
} from '@fundamental-ngx/cdk/utils';
2022
import { take } from 'rxjs/operators';
2123
import { FDP_TABLE_DRAGGABLE_DIRECTIVE } from '../constants';
@@ -24,6 +26,17 @@ import { findRowChildren, getRowParents } from '../helpers';
2426
import { TableRow, TableRowsRearrangeEvent, UpdatedDndRowsPosition } from '../models';
2527
import { TableDraggable } from '../models/directives';
2628
import { Table } from '../table';
29+
import {
30+
DOWN_ARROW,
31+
END,
32+
HOME,
33+
LEFT_ARROW,
34+
PAGE_DOWN,
35+
PAGE_UP,
36+
RIGHT_ARROW,
37+
SPACE,
38+
UP_ARROW
39+
} from '@angular/cdk/keycodes';
2740

2841
@Directive({
2942
// eslint-disable-next-line @angular-eslint/directive-selector
@@ -36,7 +49,7 @@ import { Table } from '../table';
3649
}
3750
]
3851
})
39-
export class TableDraggableDirective<T = any> extends TableDraggable<T> {
52+
export class TableDraggableDirective<T = any> extends TableDraggable<T> implements OnDestroy {
4053
/** Whether to allow for row reordering on tree tables via drag and drop. */
4154
@Input()
4255
enableRowReordering = true;
@@ -86,6 +99,11 @@ export class TableDraggableDirective<T = any> extends TableDraggable<T> {
8699
/** @hidden */
87100
dragDropInProgress = false;
88101

102+
/** @hidden */
103+
ngOnDestroy(): void {
104+
this._setDragInProgress(false);
105+
}
106+
89107
/** Sets table reference. */
90108
setTable(table: Table): void {
91109
this._table = table;
@@ -95,7 +113,7 @@ export class TableDraggableDirective<T = any> extends TableDraggable<T> {
95113
* Initiates drag&drop sequence.
96114
*/
97115
dragDropStart(): void {
98-
this.dragDropInProgress = true;
116+
this._setDragInProgress(true);
99117
}
100118

101119
/** Method called when dnd performed with the keyboard. */
@@ -126,15 +144,17 @@ export class TableDraggableDirective<T = any> extends TableDraggable<T> {
126144
dropCancelled(): void {
127145
/** After timeout to make click event handled first */
128146
this._ngZone.runOutsideAngular(() => {
129-
setTimeout(() => (this.dragDropInProgress = false));
147+
setTimeout(() => {
148+
this._setDragInProgress(false);
149+
});
130150
});
131151
}
132152

133153
/** Method called when dragged item being dropped. */
134154
dragDropItemDrop(event: FdDropEvent<TableRow>): void {
135155
/** After timeout to make click event handled first */
136156
this._ngZone.runOutsideAngular(() => {
137-
setTimeout(() => (this.dragDropInProgress = false));
157+
setTimeout(() => this._setDragInProgress(false));
138158
});
139159

140160
this._onZoneFree(() => {
@@ -193,6 +213,12 @@ export class TableDraggableDirective<T = any> extends TableDraggable<T> {
193213
);
194214
}
195215

216+
/** @hidden */
217+
private _setDragInProgress(dragging: boolean): void {
218+
this.dragDropInProgress = dragging;
219+
dragging ? this._blockScrolling() : this._enableScrolling();
220+
}
221+
196222
/** @hidden */
197223
private _isDroppedInsideItself(dropRow: TableRow, dragRow: TableRow): boolean {
198224
const dropRowParents = getRowParents(dropRow);
@@ -311,4 +337,38 @@ export class TableDraggableDirective<T = any> extends TableDraggable<T> {
311337
callback();
312338
});
313339
}
340+
341+
/** @hidden */
342+
private _blockScrolling(): void {
343+
this._table._focusableGrid._preventKeydown = true;
344+
this._table.tableContainer.nativeElement.addEventListener('DOMMouseScroll', preventDefault, false);
345+
this._table.tableContainer.nativeElement.addEventListener('wheel', preventDefault, { passive: false });
346+
this._table.tableContainer.nativeElement.addEventListener('mousewheel', preventDefault, { passive: false });
347+
this._table.tableContainer.nativeElement.addEventListener('touchmove', preventDefault, { passive: false });
348+
this._table.tableContainer.nativeElement.addEventListener('keydown', preventDefaultForScrollKeys, false);
349+
}
350+
351+
/** @hidden */
352+
private _enableScrolling(): void {
353+
this._table._focusableGrid._preventKeydown = false;
354+
this._table.tableContainer.nativeElement.removeEventListener('DOMMouseScroll', preventDefault, false);
355+
this._table.tableContainer.nativeElement.removeEventListener('wheel', preventDefault);
356+
this._table.tableContainer.nativeElement.removeEventListener('mousewheel', preventDefault);
357+
this._table.tableContainer.nativeElement.removeEventListener('touchmove', preventDefault);
358+
this._table.tableContainer.nativeElement.removeEventListener('keydown', preventDefaultForScrollKeys, false);
359+
}
360+
}
361+
362+
function preventDefault(event: Event): void {
363+
event.preventDefault();
364+
}
365+
366+
function preventDefaultForScrollKeys(event: KeyboardEvent): boolean | undefined {
367+
if (
368+
!event.altKey &&
369+
KeyUtil.isKeyCode(event, [LEFT_ARROW, RIGHT_ARROW, UP_ARROW, DOWN_ARROW, SPACE, PAGE_DOWN, PAGE_UP, END, HOME])
370+
) {
371+
preventDefault(event);
372+
return false;
373+
}
314374
}

libs/platform/src/lib/table-helpers/directives/table-virtual-scroll.directive.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import { DestroyedService, FocusableItemPosition, KeyUtil } from '@fundamental-n
33
import { ContentDensityMode } from '@fundamental-ngx/core/content-density';
44
import { BehaviorSubject, filter, Subscription } from 'rxjs';
55
import { takeUntil } from 'rxjs/operators';
6-
import { FDP_TABLE_VIRTUAL_SCROLL_DIRECTIVE, ROW_HEIGHT } from '../constants';
7-
import { TableVirtualScroll } from '../models';
6+
import { FDP_TABLE_DRAGGABLE_DIRECTIVE, FDP_TABLE_VIRTUAL_SCROLL_DIRECTIVE, ROW_HEIGHT } from '../constants';
7+
import { TableDraggable, TableVirtualScroll } from '../models';
88
import { TableScrollDispatcherService } from '../services/table-scroll-dispatcher.service';
99
import { Table } from '../table';
1010
import { DOWN_ARROW, UP_ARROW } from '@angular/cdk/keycodes';
@@ -77,6 +77,11 @@ export class TableVirtualScrollDirective extends TableVirtualScroll implements O
7777
/** @hidden */
7878
private readonly _tableScrollDispatcher = inject(TableScrollDispatcherService);
7979

80+
/** @hidden */
81+
private readonly _dndTableDirective = inject<TableDraggable>(FDP_TABLE_DRAGGABLE_DIRECTIVE, {
82+
optional: true
83+
});
84+
8085
/** @hidden */
8186
private readonly _tableRowService = inject(TableRowService);
8287

@@ -174,7 +179,7 @@ export class TableVirtualScrollDirective extends TableVirtualScroll implements O
174179
this._focusedCell = event;
175180
});
176181
}
177-
if (!this.virtualScroll || !this.bodyHeight) {
182+
if (!this.virtualScroll || !this.bodyHeight || this._dndTableDirective?.dragDropInProgress) {
178183
return;
179184
}
180185

libs/platform/src/lib/table/table.component.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
<div
2525
class="fdp-table__body fd-scrollbar"
2626
[class.fdp-table__body--virtual-scroll]="!!_virtualScrollDirective?.virtualScroll"
27+
[class.fdp-table__body--disable-scroll]="!!_dndTableDirective?.dragDropInProgress"
2728
[style.position]="
2829
!!_virtualScrollDirective?.virtualScroll && !_virtualScrollDirective?.scrollWholeRows
2930
? 'relative'

libs/platform/src/lib/table/table.component.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,3 +577,7 @@ fdk-dynamic-portal {
577577
.fd-table__intersection-spy {
578578
position: relative;
579579
}
580+
581+
.fdp-table__body--disable-scroll {
582+
overflow: hidden !important;
583+
}

0 commit comments

Comments
 (0)