akserg / ng2-dnd

Angular 2 Drag-and-Drop without dependencies
MIT License
839 stars 252 forks source link

(onDropSuccess) does not fire everywhere in dnd-droppable #59

Open KlausNie opened 8 years ago

KlausNie commented 8 years ago

If I drop an element into a droppable container, the (onDropSuccess) event should fire. However in my example

<div dnd-sortable-container [sortableData]="orders" [dropZones]="['orders']"
     dnd-droppable [allowDrop]="allowDropFunction()"
     class="col-lg-6 box">
    <div *ngFor="let o of orders; let i=index"
         dnd-draggable [dragEnabled]="true" [dragData]="o"
         dnd-sortable [sortableIndex]="i" (onDropSuccess)="updateLeft(o)"> <!-- (onDropSuccess)="updateLeft($event)" -->
        {{o.key}} {{o._id}}
    </div>
</div>

<div class="col-lg-6">
    <div *ngFor="let dep of departments" class="box">
    <div dnd-sortable-container [dropZones]="['orders']" [sortableData]="dep.nodes"
         dnd-droppable [allowDrop]="allowDropFunction()">
        <div>
            <div dnd-draggable [dragEnabled]="false" [dragData]=""
                 dnd-sortable [sortableIndex]="-1" (onDropSuccess)="updateRight(dep, {})" style="background: red" >
                {{dep.name}}
            </div>
            <div *ngFor="let o of dep.nodes; let i=index"
                 dnd-draggable [dragEnabled]="true" [dragData]="o"
                 dnd-sortable [sortableIndex]="i" (onDropSuccess)="updateRight(dep, o)">
                {{o.key}}
            </div>
        </div>
    </div>
    </div>
</div>

it is possible, to drop an element, without receiving the event.

Reproduction:

  1. take any draggable element
  2. when it is inside the container, meaning the element is already listed in the right container, move your cursor over the head of the container you want to drop it in (red field)
  3. drop the element

Result: the element is in the container, but no event is fired!

Note that the head

            <div dnd-draggable [dragEnabled]="false" [dragData]=""
                 dnd-sortable [sortableIndex]="-1" (onDropSuccess)="updateRight(dep, {})" >
                {{dep.name}}
            </div>

being like this is, my try, to overcome this problem.

What I also tried it without the dnd directives:

         <div>
            <div style="background: red" >
                {{dep.name}}
            </div>
            <div *ngFor="let o of dep.nodes; let i=index"
                 dnd-draggable [dragEnabled]="true" [dragData]="o"
                 dnd-sortable [sortableIndex]="i" (onDropSuccess)="updateRight(dep, o)">
                {{o.key}}
            </div>
        </div>

or outside of the div

<div dnd-sortable-container [dropZones]="['orders']" [sortableData]="dep.nodes"
         dnd-droppable [allowDrop]="allowDropFunction()">
         <div style="background: red" >
                {{dep.name}}
            </div>
        <div>
            <div *ngFor="let o of dep.nodes; let i=index"
                 dnd-draggable [dragEnabled]="true" [dragData]="o"
                 dnd-sortable [sortableIndex]="i" (onDropSuccess)="updateRight(dep, o)">
                {{o.key}}
            </div>
        </div>
    </div>

or even outside the dnd-droppable container
<div class="col-lg-6">
    <div *ngFor="let dep of departments" class="box">
    <div style="background: red" >
                {{dep.name}}
            </div>
    <div dnd-sortable-container [dropZones]="['orders']" [sortableData]="dep.nodes"
         dnd-droppable [allowDrop]="allowDropFunction()">
        <div>
            <div *ngFor="let o of dep.nodes; let i=index"
                 dnd-draggable [dragEnabled]="true" [dragData]="o"
                 dnd-sortable [sortableIndex]="i" (onDropSuccess)="updateRight(dep, o)">
                {{o.key}}
            </div>
        </div>
    </div>
    </div>
</div>

which does NOT work at all, which makes sense. But I'm not anymore able to pull something into an empty dnd-droppable container


I'm using: Angular version: angular 2.0.0-rc.4 Browser:

Example: PLNKR I could not find a way to make this work. Am I doing something wrong? If so what?

jacobrabjohns commented 8 years ago

Whilst onDropSuccess is not firing, and nor is onDragSuccess, onDragEnd is being fired and I have successfully used this event to get the functionality I needed. Its not perfect, but it does work.

artiz commented 7 years ago

If issue is still actual then I have found a reason of this behavior - events firing is broken by dnd directives conflict. Do not use dnd-draggable, dnd-droppable, and dnd-sortable on same element, because they shares inner state and alloDrop property is reset to false. So just insert some internal DIV if you want to get element draggable an droppable like this:

<div *ngFor="let hub of listHubs()"  class="hub" 
          dnd-draggable [dragData]="hub">
  <div class="drop-zone" dnd-droppable (onDropSuccess)="onHubDropped($event, hub)">
    <span class="name">{{ hub.name }}</span>
    <span class="clip-name">{{ hub.clipName }}</span>
  </div>

norenma commented 7 years ago

@jacobrabjohns solution almost worked for me, however, I have multiple lists and when dragging from one list to another and the dropping is outside the list my model gets updated but no callback is being triggered.

PleasantD commented 7 years ago

I have the same problem as @norenma. I move an item from one list to the other, the item appears in the list. While the mouse button is still down I move past the container and release. The model contains the correct elements, but no event is fired, so I can't fire an output event of my own.

ChrisTarasovs commented 7 years ago

anyone solved this?

karanmanshani commented 7 years ago

+1

arswaw commented 7 years ago

I'm also looking forward to a solution.

anabastos commented 7 years ago

+1

mariuspopovici commented 7 years ago

+1

pickerflicker commented 7 years ago

+1, confirmed on my end too

andrewalgabre commented 7 years ago

+1

champeng commented 7 years ago

May be it is an intentional feature, but I can see that onDropSuccess is not fired even if we have two simple sortable containers and dragging dropping elements to second list from first. You can see it live in plunker

Second thing is that as mentioned by @PleasantD here is it expected behaviour to retain the moved element in second sortable container even if user has stopped dragging outside of that container? You can see, in the plunker, this behaviour creates trouble when we have multiple containers where user can drop items. Further, it maintains the order within the first sortable container even if user moves out of the container while releasing the mouse button. Sorry for diverging from the topic, but if this is actually a feature or intended behaviour, please direct me to the doc for the same.

Plunker: https://plnkr.co/edit/dbYWEOm8ywuLmUmfIQ5e

rcfrias commented 7 years ago

I tried both onDragEnd and onDropSuccess and none of them got fired:

      <table class="sjs-table" dnd-sortable-container [sortableData]="currentImageSources" (onDropSuccess)="console.log('DROP SUCCESS')" (onDragEnd)="alert('dragEnd!')">
        <tr *ngFor="let val of currentImageSources; let i = index" dnd-sortable [sortableIndex]="i" style="height: 80px; border: solid; border-color: #1d1e1f;" >
          <td style="height: auto">
            <img [src]="val" style="height: 72px">
          </td>
        </tr>
      </table>

After trying different setups, I realized It works when the event handlers are placed in the elements to be dragged and not in the container itself. So if we have a table with dnd-sortable-container and we sort the rows (tr), then the row is the one catching the events onDropSuccess onDragEnd, etc...

champeng commented 7 years ago

@rcfrias Thanks for info. However, it is not working for me even if I put the event handlers on sortable elements. I have updated the plunk to have onDropSuccess attached to both target sortable container and sortable divs. But event is not being fired.

sachinkasana commented 6 years ago

+1

Umesh-Markande commented 6 years ago

has anyone solved this? onDropSuccess for dnd-sortable-container event not fire

dberg92 commented 6 years ago

Im also having this problem.

MorlaRamakrishna commented 6 years ago

Im also having this problem. It does not fire for md-input-container

okansarica commented 4 years ago

Try to give a dropzone attribute for every container like [dropZones]="['categorySortZone']"