Search code examples
jqueryjquery-uidraggablejquery-ui-draggablecontainment

Restrict jQuery draggable items from overlapping/colliding with sibling elements


I need to use jQuery UI to restrict the containment area for draggable object with some additional restriction. I need prevent the draggable element from overlapping with other elements within the same container. I need to allow movement in "moveInHere" area but not "butNotHere" area. Is it possible?

<div id="moveInHere">

    <div id="dragMe"> </div>

    <div id="butNotHere"> </div>

</div>


<script type="text/javascript">

    $("#dragMe").draggable({
        containment: "#moveInHere"
    });

</script>

Solution

  • Edit: New Solution

    I found a plugin for this called JQuery UI Draggable Collision. Using this, implementing your desired functionality becomes trivial. See the following jsFiddle example: http://jsfiddle.net/q3x8w03y/1/ (This uses version 1.0.2 of JQuery UI Draggable Collision, along with JQuery 1.7.2 and JQueryUI 1.1.18.)

    Here is the code:

    $("#dragMe").draggable({
        obstacle: "#butNotHere",
        preventCollision: true,
        containment: "#moveInHere"
    });
    

    Old Solution

    The following should work. It has a glitch, though. Once the divs collide, you have to "regrab" the div you are dragging, which can be a little annoying. Perhaps someone else will know how to fix this this. You can see my jsFiddle example here: http://jsfiddle.net/MrAdE/8/

    var prevOffset, curOffset;
    $("#dragMe").draggable({
        drag: function(e,ui) {
            prevOffset= curOffset;
            curOffset= $.extend({},ui.offset);
            return true;
        }
    });
    
    $("#butNotHere").droppable({
        greedy: true,
        over: function(e,ui) {
            ui.helper.offset(curOffset= prevOffset).trigger("mouseup");
        },
        tolerance: "touch"
    });​