Björn C
Björn C

Reputation: 4008

Jquery draggable & droppable event delegation: stop & drop

My problem is to get the position of the dropped element.
I use stop:option on .draggableto get the new position.

$('.elementsDiv').draggable({
  revert: 'invalid', //Revert when drop fails
  helper: 'clone', //Drag a clone
  stop: function() {
    //Dropped position.
    Stoppos = $(this).position();
  }
});

When dragged i'd like to remove the element from it's parent, and append it to it´s new parent.
This i do with .droppable

$('.flakUp, .flakDown').droppable({
    accept: '.elementsDiv',
    drop: function (event, ui) {

        //get dragged element
        var draggedElement = $(ui.draggable);

        //get dropZone
        var dropZone = $(this); 

        //Remove element from list and append it to dropZone
        draggedElement.detach().appendTo(dropZone.position(Stoppos));

        //Make element draggable
        draggedElement.draggable();
    }
});

When i remove/append, the new position will be top-left.
So i must get the dropped position from .draggable and use it in .droppable drop function to move the element to where it was dropped.

This is where my problem starts!
In console i get: Stoppos is not defined.
I guess the droppable-drop executes before draggable-stop?!

How can i solve this?
I need to create a clone, because of index problems. Therefore i also need to remove/append the element.

Upvotes: 0

Views: 1182

Answers (1)

Twisty
Twisty

Reputation: 30883

I would advise making use of the attributes of the function that are passed.

var stopPos = {};
var stopOff = {};

$('.elementsDiv').draggable({
  revert: 'invalid', //Revert when drop fails
  helper: 'clone', //Drag a clone
  stop: function(e, ui) {
    stopPos = ui.position;
    stopOff = ui.offest;
    console.log(stopPos, stopOff);
  }
});

This will give you the Position and Offset of the helper as {top, left} object. You can use these later when you're attaching the helper in your droppable.

$('.flakUp, .flakDown').droppable({
  accept: '.elementsDiv',
  drop: function (event, ui) {
    var draggedElement = $(ui.draggable);
    var dropZone = $(this); 

    //Remove element from list and append it to dropZone
    draggedElement.detach().appendTo(dropZone.position(stopPos));

     //Make element draggable
     draggedElement.draggable();
  }
});

So nothing outwardly wrong with your code, but notice one small thing, is the definition of the variable stopPos and stopOff outside of the functions. In the end it should look like:

  $(function(){
    var stopPos = {};
    var stopOff = {};

    $('.elementsDiv').draggable({
      revert: 'invalid', //Revert when drop fails
      helper: 'clone', //Drag a clone
      stop: function(e, ui) {
        stopPos = ui.position;
        stopOff = ui.offest;
        console.log(stopPos, stopOff);
      }
    });

    $('.flakUp, .flakDown').droppable({
      accept: '.elementsDiv',
      drop: function (event, ui) {
        var draggedElement = $(ui.draggable);
        var dropZone = $(this); 

        //Remove element from list and append it to dropZone
        draggedElement.detach().appendTo(dropZone.position(stopPos));

         //Make element draggable
         draggedElement.draggable();
      }
    });
  });

In this method, the variables can be accessed by both. if you only define it inside of the function, it is not accessible to other functions.

Upvotes: 0

Related Questions