Restrict jQuery draggable items from overlapping/colliding with sibling elements
Asked Answered
I

2

10

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>
Impressure answered 12/7, 2012 at 12:47 Comment(0)
D
19

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"
});​
Demb answered 12/7, 2012 at 14:1 Comment(6)
+1 Clever to use droppable's over event to trigger a mouseup.Ass
Do you know if your new solution is compatible with JQuery 1.10? I'm getting errors.Resurrection
This jsfiddle does not work anymore. Answer should be updated with the details of versions etcPerryperryman
@Perryperryman JSFiddle removed the third party files I'd uploaded for the example. Looks like you can't upload third part files any more, so I embedded them in the JavaScript section. Here's the new example: jsfiddle.net/q3x8w03y/1 I'll update the answer with versions.Demb
New solution will not work with jQuery UI 1.10 and greaterEgmont
in old solution ,, is there anything we can do in out method ......because it stucks after it touches the obstacleVicereine
S
7

This took me quite a bit of fiddling. Basically I created a droppable on the element you want to avoid, then set a boolean when the drag is over it. I then use that in an undocumented revert function override to cancel the drop. It only works if #dragMe is fully over #butNotHere:

$(document).ready(function(){
    var shouldCancel = false;
    $('#dragMe').draggable({
        containment: '#moveInHere',
        revert: function(){
            if (shouldCancel) {
                shouldCancel = false;
                return true;
            } else {
                return false;
            }
        }
    });
    $('#butNotHere').droppable({
        over: function(){
            shouldCancel = true;
        },
        out: function(){
            shouldCancel = false;
        }
    });
});

Check out the working demo and feel free to play with it: http://jsfiddle.net/H59Nb/31/

Shadowy answered 12/7, 2012 at 13:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.