reppners / ngx-drag-drop

Angular directives using the native HTML Drag And Drop API
https://reppners.github.io/ngx-drag-drop/
BSD 3-Clause "New" or "Revised" License
299 stars 118 forks source link

buttons with dndDraggable / dndHandle are not draggable in Firefox #25

Closed inspirassion closed 5 years ago

reppners commented 6 years ago

Version?

ivopan commented 5 years ago

Same here, I have just started testing this library. Chrome works, firefox does not. OS is Ubuntu 18.04, Firefox 61.0.1. Everything actual (from Ubuntu repositories). Developing using vscode and agular-cli.

ng --version: `Angular CLI: 6.0.8 Node: 8.10.0 OS: linux x64 Angular: 6.0.9 ... animations, common, compiler, compiler-cli, core, forms ... http, language-service, platform-browser ... platform-browser-dynamic, router

Package Version

@angular-devkit/architect 0.6.8 @angular-devkit/build-angular 0.6.8 @angular-devkit/build-optimizer 0.6.8 @angular-devkit/core 0.6.8 @angular-devkit/schematics 0.6.8 @angular/cdk 6.4.1 @angular/cli 6.0.8 @angular/material 6.4.1 @ngtools/webpack 6.0.8 @schematics/angular 0.6.8 @schematics/update 0.6.8 rxjs 6.2.2 typescript 2.7.2 webpack 4.8.3`

reppners commented 5 years ago

Thx for the detailed info. I've tested by using the demo at https://reppners.github.io/ngx-drag-drop/ with Firefox 61.0.1 on macOS and Ubuntu 18.04 - both work without issues.

Can you reproduce with a stackblitz? https://stackblitz.com/edit/ngx-drag-drop-issue-template

ivopan commented 5 years ago

Thanks for info. Yes, I can verify that example really works in Firefox. I have just tested my app on macOS - Safari works, Chrome works, Firefox does NOT work. So something else should be causing the problem. My app is relatively large and uses exclusively Angular + Angular Material. I will try to figure it out, but debugging drag&drop won't be easy. Yes - one more thing, somewhere else in the same app I use ng2-file-upload and is also uses drop. But my guess is it does not cause problem with Firefox.

ivopan commented 5 years ago

I have more info - perhaps I have found it. It WORKS in firefox ... but not fully! I have div dropzone, inside that div dndPlaceholder and then items are populated using *ngFor. It works for items, that were present on component start, BUT when I add new components later to the array, they are visible (of course) but they are NOT draggable. It seems that in firefox there is a problem with reinstantiating draggable directive after change.

reppners commented 5 years ago

Thanks, that's very helpful! I'll try to reproduce and report back my findings.

ivopan commented 5 years ago

Hmm, I had a time to test it more and with simple items (handle and div with text) it works! So problem is somewhat complex. But my data are not so complicated = div with handle few buttons and div with text. I will try to strip it down step by step ...

ivopan commented 5 years ago

Aha. More info - it depends on dndHandle (I need to use it). This code works: ` <div *ngFor="let x of dndTestData2" [dndDraggable]="x" dndEffectAllowed="copyMove" (dndStart)="onDragStart($event)" (dndEnd)="onDragEnd($event)">

drag_handle
                <span>{{x.code}}</span>
            </div>

`

And this code does NOT work = drag does not start: ` <div *ngFor="let x of dndTestData1" [dndDraggable]="x" dndEffectAllowed="copyMove" (dndStart)="onDragStart($event)" (dndEnd)="onDragEnd($event)">

                <div class="item">
                    {{x.code}}
                </div>
            </div>

`

The only difference is, that non working version has dndHandle on button = in this case angular material button. But both versions are rendered inside browser DOM directly under that draggable div tag.

ivopan commented 5 years ago

Hmm, still it is problematic. I have forgot to write that I am trying to sort list. (div's in div).

In Chrome I receive events in this order (inside my component): onDragStart, onDrop, onDraggable, onDragEnd.

While in Firefox I receive this: onDragStart, onDraggable, onDragEnd

Placeholder is properly moved there - i have tested to put to both possible places = 1st or last element. It is properly removed from there, inserted as 1st element and left there.

So now I think the problem can be somewhere in DOM manipulation ... when the DOM is more complex.

ivopan commented 5 years ago

Here is full template: (I catch for testing all events but actually I need dndMoved only)

            <div dndDropzone [dndDisableIf]="!moreUsedItems" dndEffectAllowed="copyMove" (dndDrop)="onDrop($event)" [dndHorizontal]="false"
                class="column dndList">
                <div *ngFor="let si of data.usedItems" class="usedItem" [dndDisableIf]="!moreUsedItems" [dndDraggable]="si" dndEffectAllowed="copyMove"
                    (dndStart)="onDragStart($event)" (dndEnd)="onDragEnd($event)" (dndCopied)="onDragged(si, 'copy')" (dndLinked)="onDragged(si, 'link')"
                    (dndMoved)="onDragged(si, 'move')" (dndCanceled)="onDragged(si, 'none')">
                    <!-- <button mat-icon-button [class.invisible]="!moreUsedItems" dndHandle>
                        <mat-icon>drag_handle</mat-icon>
                    </button> -->
                    <mat-icon dndHandle>drag_handle</mat-icon>
                    <button mat-icon-button (click)="redirectUsedItem(si.code)" i18n-matTooltip="@@Change_direction_sort_item_button" matTooltip="Change direction">
                        <mat-icon *ngIf="si.ascending">arrow_upward</mat-icon>
                        <mat-icon *ngIf="!si.ascending">arrow_downward</mat-icon>
                    </button>
                    <div class="item">
                        {{data.getLabel(si.code)}}
                    </div>
                    <button mat-icon-button (click)="unuseItem(si.code)" i18n-matTooltip="@@Remove_sort_item_button" matTooltip="Remove">
                        <mat-icon>delete</mat-icon>
                    </button>
                </div>
                <div dndPlaceholderRef class="dndPlaceholder"></div>
            </div>
reppners commented 5 years ago

Regarding buttons not being draggable - this is a bug in firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=568313

The other issue I'll have to reproduce, thanks for the template.

ivopan commented 5 years ago

Oh, I was not aware of that, thanks. I have replaced button with div => dnd now works but problem with proper placeholder was still there.

And I have (hopefully) found why: Simple usage of div and mat-icon inside caused the icon to be positioned to the top of div, so it was not vertically aligned with the rest ... and placeholder had problems. I have vertically centralized it using css and placeholder now works properly ! So now everything works.

Here are relevant code parts:

<div class="buttonLikeLayout" dndHandle>
    <mat-icon class="buttonLikeLayoutIcon">drag_handle</mat-icon>
</div>
.buttonLikeLayout {
    width: 40px;
    height: 40px;
    flex-shrink: 0;
    line-height: 40px;
    border-radius: 50%;
    cursor: grab;
    text-align: center;
}

.buttonLikeLayoutIcon {
    vertical-align: middle;
}
reppners commented 5 years ago

Glad you were able to solve your issues. I will leave this open until the firefox button thing is documented.