marceljuenemann / angular-drag-and-drop-lists

Angular directives for sorting nested lists using the HTML5 Drag & Drop API
MIT License
2.16k stars 713 forks source link

Multiple Placeholders showing when dragging into a container #384

Open spreston077 opened 7 years ago

spreston077 commented 7 years ago

Has anyone else experienced an issue which causes two placeholders to be displayed at once when dragging an item into a container?

MaZZly commented 7 years ago

I've seen it in nested lists, where there comes a placeholder both for the parent list and the hovered list.

MaZZly commented 7 years ago

I was able to reduce the occurance of this by plaiying around with paddings/margins on the nested lists..

ChrisGarber-Medlever commented 7 years ago

I'm seeing this when I drag an element into a nested element from the bottom

calum-gd commented 7 years ago

I managed to fix this issue, however I think my solution is probably a bit too specific to my implementation of the plugin to be a valid pull request (it relies on the DOM structure of the nesting containers matching mine). However the concept should be adaptable to any implementation.

 if (listItemNode.parentNode == listNode && listItemNode != placeholderNode) {
    // If the mouse pointer is in the upper half of the list item element,
    // we position the placeholder before the list item, otherwise after it.
    var rect = listItemNode.getBoundingClientRect();
    if (listSettings.horizontal) {
      var isFirstHalf = event.clientX < rect.left + rect.width / 2;
    } else {
      var isFirstHalf = event.clientY < rect.top + rect.height / 2;
    }

      // ~~~ fix for duplicating placeholder bug ~~~
      // check if target is within a container
      if(listItemNode.parentNode.parentNode.classList.value === 'ng-scope'){

          // check if the parent list which contains the container still contains a placeholder
          var duplicate = listNode.parentNode.parentNode.parentNode.parentNode.parentNode.getElementsByClassName('dndPlaceholder')[1];

          // if it does, remove it
          if(duplicate){
              duplicate.remove();    
          }
      }

    listNode.insertBefore(placeholderNode,
        isFirstHalf ? listItemNode : listItemNode.nextSibling);
  }
}

I have included surrounding code for context: excerpt starts at line 330.

Hope this helps someone in my shoes!

Nitesh2206 commented 7 years ago

This issue happens everywhere for the nested lists. Also for the demos.

Nitesh2206 commented 7 years ago

This worked for me and i guess it will work for everyone. I have removed the earlier placeholder before inserting a new one. Line no:318

// Make sure the placeholder is shown, which is especially important if the list is empty. if (placeholderNode.parentNode != listNode) { //Before inserting the new placeholder remove the earlier one. var duplicate = document.getElementsByClassName("dropzone")[0].getElementsByClassName('dndPlaceholder')[0]; if (duplicate) { duplicate.remove(); } element.append(placeholder); }

AdeyinkaAdegbenro commented 6 years ago

In my own case the placeholders lingered even after insertion/dragging into my nested list. I fixed it by addingdnd-inserted='setStyle("dndPlaceholder", "display", "none")' and dnd-dragover=setStyle("dndPlaceholder", "display", "block") to my div with dnd-list attribute. In my controller I add

      $scope.setStyle = function(elem, prop, style) {
        // a work-around the dndlibrary bug where placeholders linger in nested
        // drag and drop user interfaces
        var elements = document.getElementsByClassName(elem)
        for (var i = 0; i < elements.length; i++) {
          elements[i].style[prop] = style
        }
        return true
      }

What this does is set the display of all lingering placeholders to none once the item is inserted using 'dnd-inserted', also resetting the display of all placeholder to block on dragover using 'dnd-dragover'. I write this in hope that it might help someone facing this same issue.

ZtheLeader commented 6 years ago

@AdeyinkaAdegbenro Your trick worked for me as well! Thanks mate! 👍