ng2-dnd: (onDropSuccess) does not fire everywhere in dnd-droppable

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:

  • Chrome Version 52.0.2743.116 (64-bit)
  • Firefox 47.0

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

About this issue

  • Original URL
  • State: open
  • Created 8 years ago
  • Reactions: 18
  • Comments: 19

Most upvoted comments

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.

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…

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.

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>
</div>