Change position of divs with jquery drag an drop

Stefan picture Stefan · Mar 11, 2013 · Viewed 54k times · Source

I'm trying to build a website where the user can drag some items (one item in on div) to other divs on the page. It' not a table or so, just divs somewhere on the page.

With html5 drag&drop it works well, now I try to do this for mobile devices. I can drag items to divs, drop them there and block this dropzone, because only one element should be in a dropzone. I also can drag this element to another div or somewhere else on the page (droppable areas only work on first time a div is dropped) if I've had make a mistake but then I cannot drop another item in the div which is now empty again.

How can I enable dropping in this Dropzone again?

And is it possible to two change the position of two divs if one is dragged on another?

Here is the relevant part of my code:

<script type="text/javascript">
$ (init);
function init() {
    $(".dragzones").draggable({
        start: handleDragStart,
        cursor: 'move',
        revert: "invalid",
    });
    $(".dropzones").droppable({
        drop: handleDropEvent,
        tolerance: "touch",              
    });
}
function handleDragStart (event, ui) {}       
function handleDropEvent (event, ui) {
    $(this).droppable('disable');
    ui.draggable.position({of: $(this), my: 'left top', at: 'left top'});
    ui.draggable.draggable('option', 'revert', "invalid");
}
</script>
<body>
<div id="alles">
<div class="dropzones" id="zone1"><div class="dragzones" id="drag1">Item 1</div></div>
<div class="dropzones" id="zone2"><div class="dragzones" id="drag2">Item 2</div></div>
<div class="dropzones" id="zone3"><div class="dragzones" id="drag3">Item 3</div></div>
<div class="dropzones" id="zone4"><div class="dragzones" id="drag4">Item 4</div></div>
    <div class="dropzones" id="zone11"></div>
    <div class="dropzones" id="zone12"></div>
    <div class="dropzones" id="zone13"></div>
    <div class="dropzones" id="zone14"></div>   
</div>
</body>

EDIT: Here is the now working page: Drag&Drop Task

Answer

Gajotres picture Gajotres · Mar 18, 2013

Here's a working example: http://jsfiddle.net/Gajotres/zeXuM/

I think all of your problems are solved here.

  • enable/disable dropping works
  • elements returning no longer drops them below other elements
  • elements returning no longer hides/remove them
  • better elements positioning (it looks better)
  • it works on mobile devices (tested on Android 4.1.1 Chrome and iPhone)

Here's a jQuery code used:

$(document).on('pageshow', '#index', function(){       
    $(".dragzones").draggable({
        start: handleDragStart,
        cursor: 'move',
        revert: "invalid",
    });
    $(".dropzones").droppable({
        drop: handleDropEvent,
        tolerance: "touch",              
    });
});

function handleDragStart (event, ui) { }

function handleDropEvent (event, ui) {
    if (ui.draggable.element !== undefined) {
        ui.draggable.element.droppable('enable');
    }
    $(this).droppable('disable');
    ui.draggable.position({of: $(this),my: 'left top',at: 'left top'});
    ui.draggable.draggable('option', 'revert', "invalid");
    ui.draggable.element = $(this);
}

    // This is a fix for mobile devices

/iPad|iPhone|Android/.test( navigator.userAgent ) && (function( $ ) {

var proto =  $.ui.mouse.prototype,
_mouseInit = proto._mouseInit;

$.extend( proto, {
    _mouseInit: function() {
        this.element
        .bind( "touchstart." + this.widgetName, $.proxy( this, "_touchStart" ) );
        _mouseInit.apply( this, arguments );
    },

    _touchStart: function( event ) {
         this.element
        .bind( "touchmove." + this.widgetName, $.proxy( this, "_touchMove" ) )
        .bind( "touchend." + this.widgetName, $.proxy( this, "_touchEnd" ) );

        this._modifyEvent( event );

        $( document ).trigger($.Event("mouseup")); //reset mouseHandled flag in ui.mouse
        this._mouseDown( event );

        //return false;           
    },

    _touchMove: function( event ) {
        this._modifyEvent( event );
        this._mouseMove( event );   
    },

    _touchEnd: function( event ) {
        this.element
        .unbind( "touchmove." + this.widgetName )
        .unbind( "touchend." + this.widgetName );
        this._mouseUp( event ); 
    },

    _modifyEvent: function( event ) {
        event.which = 1;
        var target = event.originalEvent.targetTouches[0];
        event.pageX = target.clientX;
        event.pageY = target.clientY;
    }

});

})( jQuery );

Original author of a touchFix plugin used in this example is Oleg Slobodskoi.