Search code examples
javascriptjquery-uijquery-ui-draggablejquery-ui-sortablejquery-ui-droppable

On dropping a component its adding it more than once on droppable


I am using custom helper method which is returning a <div>, on dropping that <div> its adding it more than one time. Please look at the code to understand it better

var dropHelp = true;


$(".product").draggable({
revert: 'invalid',
cursorAt: { top: -12, left: -20 },
 connectToSortable: ".droppable",
helper: function(event) {
  return $('<div class="helper">Helper</div>');
}
});
$(".droppable").sortable({
  placeholder: "ui-state-highlight"
}).disableSelection();
$(".droppable").droppable({
drop: function(event, ui) {
    if(dropHelp){
       //clone and remove positioning from the helper element
       var newDiv = $(ui.helper).clone(false)
           .removeClass('ui-draggable-dragging')
           .css({position:'relative', left:0, top:0});            
       $(this).append(newDiv);

    //drop the draggable source element
    } else {
       $(this).append(ui.draggable);
    }
 }
 });

$('#dropDrag').click(function(){
dropHelp = !dropHelp;
});

Here's the HTML

<button id="dropDrag">Toggle drop "Helper" or "Draggable"</button><br/><br/><br/>

<div class="product">Product 1</div>
<div class="product">Product 2</div>
<div class="product">Product 3</div>

<div class="droppable">Drop Target</div>

The full code can be find here.

I found out if we remove the connectToSortable property in draggable it will work fine. But i need that property and i am not getting the reason why it's behaving this way when connectToSortable is set.


Solution

  • Your drop() gets called twice because connectToSortable is also triggering a drop(). (Sortable is already a droppable)

    I have edited your code to get the same result with receive function of sortable

    DEMO

    var dropHelp = true;
    
    
      $(".product").draggable({
        revert: 'invalid',
        cursorAt: { top: -12, left: -20 },
         connectToSortable: ".droppable",
        helper: function(event) {
          return $('<div class="helper">Helper</div>');
        },
          stop: function(){
            $(this).css({opacity:1});
        },
           start: function(){
            $(this).css({opacity:0});
        },
      });
      $(".droppable").sortable({
          placeholder: "ui-state-highlight",
          receive: function(event, ui) {
              if(dropHelp){
               //clone and remove positioning from the helper element
               var newDiv = $(ui.helper).clone(false)
                   .removeClass('ui-draggable-dragging')
                   .css({position:'relative', left:0, top:0});            
               $(this).append(newDiv);
    
            //drop the draggable source element
            } else {
               $(this).append(ui.draggable);
            }
    
      }
      }).disableSelection();
    
    
    $('#dropDrag').click(function(){
        dropHelp = !dropHelp;
    });