Search code examples
jquerydraggabledroppable

jQuery Droppable and Draggable


I have a little application where you can drag a box around in a container, and also switch places with another one, which is buggy at the moment. They switch places like jQuery sortable, but I'm having a problem with Droppable. with the over event, it only activates once while holding down the mouse.

http://jsfiddle.net/44SAh/

This is what I have so far, try dragging a box down over another one, and then back up again, without letting go of the left mouse button. It starts to glitch. Thats because the over event only activates once per click. Is there a workaround for this, I want to be able to drag a box up and down and have the same consistency where they switch places, such as sortable. And no I can't use sortable because the boxes have to be able to overlap to an extent, plus move around freely.


Solution

  • Here's a working solution for you. Basically you cache the position when you start dragging something. Then when you are over a droppable, you swap the droppable's position with the start position, update the draggable's start position, and update the underlying droppable data structure to mark it as out, and correct the offset. Here's a jsfiddle: http://jsfiddle.net/fordlover49/BwvK4/

    $(function() {
        $(".ui-widget-content").draggable({
            grid: [5, 5],
            start: function(event, ui) {
                // cache the position we were at when we started dragging.
                $(this).data("startPos", ui.position);
            },
            stack: ".ui-widget-content"
        });
    
        $(".ui-widget-content").droppable({
            tolerance: 'intersect',
            over: function(event, ui) {            
                var offset = $(ui.draggable).data("startPos");
                // update draggable's cached position to what the droppable was
                $(ui.draggable).data("startPos", {
                    top: $(this).position().top,
                    left: offset.left});
    
                // swap droppable positions with dragging's original pos.
                $(this).css("top", offset.top);
    
                // clear the over events, and update the droppable's offset.
                $(this).data("droppable").isout = 1;
                $(this).data("droppable").isover = 0;            
                $(this).data("droppable").offset = $(this).offset();
            }
        });
    });