Draggable limited in movement - javascript

I would like to create a big draggable element and put it into a smaller container that limits its movement, so 2 of the draggable sides must touch the container/container's sides.
I also want that the draggable object will be draggable from anywhere in the frame, and not only while clicking on the object itself.
I saw that jQuery provides a nice draggable object:
http://docs.jquery.com/UI/Draggable
Here is an example I made of what is allowed and what is not:

You should set the containment to that object like following:
$(".selector")
.draggable({
containment: "parent"
});
Here is doco

Related

Contain draggable to multiple elements

I write a userscript for a website, and the script includes a jQuery UI draggable. Greatly simplified, the site has two rows, and each row has two divs placed horizontally.
The site layout previously used two columns with inner divs instead of rows. The draggable was constrained to the right column's parent, which is exactly what we wanted. Now, however, there's no way to constrain to the right "column" because that column no longer exists in the DOM.
Is there a way to fluidly contain the draggable div to the right column of divs without the old parent element? I can add elements to the DOM (or do whatever) if needed, we have the full power of jQuery and jQuery UI available. I know it would be possible to use a droppable on the top right div, but from what I understand that would cause the draggable to snap between the two. If that's the only option then I'll do that, but if there's another method I would love to see it.
FIDDLE
<div id="outercontainer">
<div id="toprow">
<div id="topleft"></div>
<div id="topright"></div>
</div>
<div id="bottomrow">
<div id="bottomleft"></div>
<div id="bottomright"></div>
</div>
</div>
<div id="dragme"></div>
The actual containment value used in constraining position is an array of coordinates that's being calculated based on the object you set in the options themselves. But you can access this containment property on the draggable instance and modify them as you wish. The only restriction is that it needs to be a rectangle, you cannot mix shapes.
In your case, you can simply work out the coordinates from the elements.
$("#dragme").draggable({
// You still need to set a value for containment
// else it won't be checked when evaluating the position
containment: 'document',
start: function(e, ui) {
// You simply set a left, top, right, bottom coordinates.
// You need to set it on start so if the elements have been
// resized, the containment follows.
var cont = [
$('#topleft').offset().left + $('#topleft').outerWidth(),
$('#toprow').offset().top,
$('#toprow').offset().left + $('#toprow').outerWidth() - ui.helper.width(),
$('#bottomrow').offset().top + $('#bottomrow').outerHeight() - ui.helper.height(),
]
$(this).draggable('instance').containment = cont;
}
});
https://jsfiddle.net/nxxbh8eL/

How can I stop a JcanvaScript draggable?

How stop draggable JcanvaScript library?
For example a picture, in cases when drag-and-drop goes beyond the canvas element and I don't want to allow pictures to go beyond it.
jc('#img1').draggable({
drag: function(){
point=jc('#img1').position();
if(point.x<0){
//here stop draggable image
//these options don't work
//this.draggable('pause');
//return;
//jc.pause();
}
}
});
Wow! This was actually a really horrible problem. What makes it really horrible is that JCanvasScript doesn't fire onRelaseOutside events.
I've posted a solution here: http://jsfiddle.net/qpuGw/
You will not be able to drag the circle closer that 100px from the left-hand side.
The gist is:
If your object moves outside of a bounding box: (a) set clone it and (b) set it to invisible.
If your object moves back inside your bounding box: (a) delete the clone and (b) set your object to visible again
If the user releases the object: do the same as (2) above.
Good luck!

jQueryUI - moving draggable back to original position, even after dropping in droppable

I have a draggable element that I am dragging into one of various droppable areas. However, I want the draggable item to always return to its original position, even if it was dragged into a droppable area (the droppable areas handle their own events when the draggable is dropped onto them). Is there a way to do this?
I notice that returning true or false from the stop() function in draggable affects both its return to original position as well as whether or not it triggers the droppable's drop() function. Is there a way to handle these separately?
It's kinda a hack but when you have
$('yourelement').draggable({revert:true});
will revert it no matter if it drops or not. And it will still fire the drop event on the droppable element.
Do you want your droppables to accept other elements? If not, you can set the 'accept' option of the droppable to 'false'
$('.foo').droppable('option','accept',false);

jquery - making dropped objects draggable

how can i make a dragged object into a droppable become "draggable" again?
i tried adding the object by using "append" in jquery. but after seeing/appending the object inside the droppable div. i cannot drag it.
here is my work http://piratelufi.com/flowers/
the images that are already in the gray area can be dragged and resized.
the images in the lower left area, when dragged into the gray area will add it there but cannot be dragged.
i even tried adding to ui-draggable class into the element that needs to be dragged.
Draggebles remains draggable even after drop. Check jQuery UI Droppable

jQuery UI Draggable, Snapping to a Grid

I have two containers. A thumbnail container, and a "page" container. Both are divs. Thumbnails can be dragged back and forth between the two containers. I have revert on the thumbnails set to 'invalid', so they snap back to one of the two containers if they are dropped outside of either one of them.
The thumbnails must snap to a 20x20 grid inside the "page" container. This is so client the client can put the thumbnails in the "page" container in any place, but still be able to line them up neatly.
The problem is the draggable 'grid' option doesn't seem to work too well for this. It seems the "grid" is determined by the draggables location when you start dragging it, rather than acting as if the page has a real grid that can be snapped to.
Is there a way to fix this so the grid is based off the "page" container, rather than the position of the draggable when you start dragging it?
Check the snapping example on the Jquery UI Site:
http://jqueryui.com/demos/draggable/#snap-to
You can take their same example and specify both a grid and a snap parameter.
Then the snap will be based off of the top left corner of the snap selector.
$( "#draggable5" ).draggable({ snap: ".ui-widget-header", grid: [ 80, 80 ] });
The example on the Jquery site will now let the "80x80" box snap based on the big container.
In your situation it might be easiest to create a div with 100% width and height, then set the snap: selector (using css selectors) to that div, then specifying a grid to snap to...
Good Luck
Maybe you could try to round the starting position to the nearest 20 pixels by using the start event on the draggable.
Something like (untested...):
$('#draggable').draggable(
{snap : grid: [20,20]},
{start : function(event, ui) {
var startPosition = $(ui.draggable).position();
$(ui.draggable).css({
'left' : (Math.round(startPosition.left/20)*20)+'px',
'top' : (Math.round(startPosition.top/20)*20)+'px'});
}
}
);
I'm trying myself to achieve that but I'm cloning the dragged element to another container so that's even more tricky ;-)
I still have to figure out how to set the position of the helper in the start event...
Of course it will only work if the starting position is already absolute (like when dragged).
As a matter of fact, I've nearly achieved it by applying this method to the stop event and removing the grid property.
You don't get any visual feedback when moving the object around because there's no grid per se anymore, but when dropping it, it goes to your own grid:
stop: function(event, ui) {
var stopPosition = $(ui.draggable).position();
$(ui.draggable).css({'left' : (Math.round(stopPosition.left/20)*20)+'px', 'top' : (Math.round(stopPosition.top/20)*20)+'px'});
}
Here's a working example:
http://jsfiddle.net/qNaHE/3/

Categories