Restrict jQuery draggable items from overlapping/colliding with sibling elements
Solution 1
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"
});
Solution 2
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/
vaclav_o
Updated on December 22, 2020Comments
-
vaclav_o over 3 years
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>
-
TJ VanToll almost 12 years+1 Clever to use
droppable
'sover
event to trigger amouseup
. -
THE JOATMON almost 11 yearsDo you know if your new solution is compatible with JQuery 1.10? I'm getting errors.
-
Kukeltje over 8 yearsThis jsfiddle does not work anymore. Answer should be updated with the details of versions etc
-
ihake over 8 years@Kukeltje 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.
-
Daniel Kobe about 8 yearsNew solution will not work with jQuery UI 1.10 and greater
-
Amar Singh almost 8 yearsin old solution ,, is there anything we can do in
out
method ......because it stucks after it touches the obstacle