diff --git a/projects/common/components/input-elements/drop-list/drag-operator.service.ts b/projects/common/components/input-elements/drop-list/drag-operator.service.ts index af80cce60527c17a5a72f705777187d14339f287..56f2370f2fd96f16b43c8ce9acd38e5bb46d3337 100644 --- a/projects/common/components/input-elements/drop-list/drag-operator.service.ts +++ b/projects/common/components/input-elements/drop-list/drag-operator.service.ts @@ -9,7 +9,7 @@ import { DragOperation } from 'common/components/input-elements/drop-list/drag-o export class DragOperatorService { dropLists: { [id: string]: DropListComponent } = {}; dragOperation: DragOperation | undefined; - + isDragActive = false; registerComponent(comp: DropListComponent): void { this.dropLists[comp.elementModel.id] = comp; @@ -19,6 +19,7 @@ export class DragOperatorService { item: DragNDropValueObject, dragType: 'mouse' | 'touch') { this.dragOperation = new DragOperation(sourceElement, sourceListComponent, sourceIndex, item, dragType, this.dropLists); + this.isDragActive = true; this.initDrag(); } @@ -36,22 +37,15 @@ export class DragOperatorService { this.dropLists[listID].cdr.detectChanges(); }); } - if (this.dragOperation.dragType === 'mouse') this.setListItemListeners(); } endDrag(): void { if (!this.dragOperation) throw new Error('dragOP undefined'); + this.isDragActive = false; this.dragOperation.sourceElement.classList.remove('show-as-placeholder'); this.dragOperation.sourceElement.style.pointerEvents = 'auto'; - this.dragOperation.placeholderElement?.classList.remove('show-as-placeholder'); - this.resetListEffects(); - if (this.dragOperation.dragType === 'mouse') { - Object.values(this.dropLists).forEach(listComp => { - listComp.stopListenForHover(); - }); - } } private resetListEffects(): void { @@ -68,7 +62,7 @@ export class DragOperatorService { if (!this.dragOperation) throw new Error('dragOP undefined'); const targetListComp = this.dropLists[listId]; this.dragOperation.targetComponent = targetListComp; - this.isListHovered = true; + this.isListHovered = true; if (targetListComp.elementModel.isSortList) { if (this.dragOperation.sourceComponent !== targetListComp) { this.addSortPlaceholder(); @@ -94,13 +88,7 @@ export class DragOperatorService { if (!this.dragOperation) throw new Error('dragOP undefined'); this.dragOperation.targetComponent = undefined; this.dragOperation.sortingPlaceholderIndex = undefined; - this.isListHovered = false; - } - - private setListItemListeners(): void { - this.dragOperation?.eligibleTargetListsIDs.forEach(listID => { - this.dropLists[listID].listenForHover(); - }); + this.isListHovered = false; } positionSortPlaceholder(targetIndex: number): void { @@ -112,6 +100,11 @@ export class DragOperatorService { this.dragOperation.sortingPlaceholderIndex = targetIndex; } + isListEligible(listID: string): boolean { + if (!this.dragOperation) throw new Error('dragOP undefined'); + return this.dragOperation.eligibleTargetListsIDs.includes(listID); + } + handleDrop(): void { if (!this.dragOperation) throw new Error('dragOP undefined'); if (this.dragOperation.sourceComponent && this.dragOperation.targetComponent && diff --git a/projects/common/components/input-elements/drop-list/drop-list.component.ts b/projects/common/components/input-elements/drop-list/drop-list.component.ts index a1e6517dd5f117707b9878a5ec213349f09309a1..7181302ebb78e43f55d1bbef0cd6a4e8918ecaa1 100644 --- a/projects/common/components/input-elements/drop-list/drop-list.component.ts +++ b/projects/common/components/input-elements/drop-list/drop-list.component.ts @@ -34,6 +34,8 @@ import { DragOperatorService } from './drag-operator.service'; [style.text-decoration]="elementModel.styling.underline ? 'underline' : ''" [style.background-color]="elementModel.styling.backgroundColor" (touchstart)="elementFormControl.markAsTouched()" + (mouseenter)="dragOpService.isDragActive && dragEnter()" + (mouseleave)="dragOpService.isDragActive && dragLeave()" (click)="elementFormControl.markAsTouched()"> <div *ngFor="let item of viewModel; let i = index;" class="drop-list-item" [class.image-item]="item.imgSrc" @@ -42,6 +44,7 @@ import { DragOperatorService } from './drag-operator.service'; (dragStart)="dragStart($event, item, i, this)" (dragMove)="dragMove($event)" (dragEnd)="dragEnd()" + (mouseenter)="dragOpService.isDragActive && listItemDragEnter(i)" [style.color]="elementModel.styling.fontColor" [style.font-size.px]="elementModel.styling.fontSize" [style.font-weight]="elementModel.styling.bold ? 'bold' : ''" @@ -70,10 +73,6 @@ export class DropListComponent extends FormElementComponent implements OnInit { isHovered = false; isHighlighted = false; - private unlistenMouseEnter: (() => void) | undefined; - private unlistenMouseLeave: (() => void) | undefined; - private unlistenItemMouseEnter: (() => void)[] = []; - constructor(public dragOpService: DragOperatorService, public elementRef: ElementRef, private renderer2: Renderer2, public cdr: ChangeDetectorRef, private overlay: Overlay) { super(elementRef); @@ -99,6 +98,9 @@ export class DropListComponent extends FormElementComponent implements OnInit { } dragEnter(): void { + // Workaround for the mouseenter event after reordering, thus triggering a source index reset. + if (this.dragOpService.isListHovered) return; + if (!this.dragOpService.isListEligible(this.elementModel.id)) return; this.isHovered = true; this.dragOpService.setTargetList(this.elementModel.id); this.cdr.detectChanges(); @@ -120,34 +122,9 @@ export class DropListComponent extends FormElementComponent implements OnInit { document.body.classList.remove('dragging-active'); // remove class for cursor while dragging } - listenForHover() { - this.unlistenMouseEnter = this.renderer2.listen(this.droplistRef?.nativeElement, 'mouseenter', () => { - // Workaround for Windows+Firefox, which creates the event after reordering, thus triggering a source index reset. - if (this.dragOpService.isListHovered) return; - this.dragEnter(); - }); - this.unlistenMouseLeave = this.renderer2.listen(this.droplistRef?.nativeElement, 'mouseleave', () => { - this.dragLeave(); - }); - - if (this.elementModel.isSortList) { - this.droplistItems?.toArray() - .forEach(listItem => { - this.unlistenItemMouseEnter.push( - this.renderer2.listen(listItem.nativeElement, 'mouseenter', (event: MouseEvent) => { - const targetIndex = Array.from(this.droplistRef?.nativeElement.children).indexOf(event.target); - this.dragOpService.positionSortPlaceholder(targetIndex); - this.cdr.detectChanges(); - }) - ); - }); - } - } - - stopListenForHover() { - this.unlistenMouseEnter?.(); - this.unlistenMouseLeave?.(); - this.unlistenItemMouseEnter.forEach(listener => listener()); + listItemDragEnter(index: number): void { + if (!this.elementModel.isSortList) return; + this.dragOpService.positionSortPlaceholder(index); } initDragImageOverlay() {