I am wondering if there is a way to make the jQuery draggable to only drag straight up, down and left, right. I want to prevent the user from dragging a div diagonally. Using the grid option in the draggable UI is not possible in my situation.
http://jqueryui.com/demos/draggable/#constrain-movement
How is this possible?
Thanks!
jQueryUI supports two methods for controlling dragging on a fixed track.
You can use the axis option to limit dragging movement on a particular axis. For instance:
$('.draggable_horiz').draggable({axis: "x"});
More Info here: http://api.jqueryui.com/draggable/#option-axis
You can constrain movement using an element or an array of x/y coordinates that define a bounding box.
$('.draggable_track').draggable({ containment: [0,0, 250, 24] });
or to just use the parent element as a reference track:
$('.draggable_track').draggable({ containment: 'parent' });
More info here: http://api.jqueryui.com/draggable/#option-containment
I hope this helps.
I wrote a plugin that allows moving a draggable in both axes. It gets the job done but it would be better-implemented as a jQuery UI widget rather than a simple jQuery plugin.
Hosted Demo: http://jsbin.com/ugadu/1 (Editable via http://jsbin.com/ugadu/1/edit)
Plugin code:
$.fn.draggableXY = function(options) {
var defaultOptions = {
distance: 5,
dynamic: false
};
options = $.extend(defaultOptions, options);
this.draggable({
distance: options.distance,
start: function (event, ui) {
ui.helper.data('draggableXY.originalPosition', ui.position || {top: 0, left: 0});
ui.helper.data('draggableXY.newDrag', true);
},
drag: function (event, ui) {
var originalPosition = ui.helper.data('draggableXY.originalPosition');
var deltaX = Math.abs(originalPosition.left - ui.position.left);
var deltaY = Math.abs(originalPosition.top - ui.position.top);
var newDrag = options.dynamic || ui.helper.data('draggableXY.newDrag');
ui.helper.data('draggableXY.newDrag', false);
var xMax = newDrag ? Math.max(deltaX, deltaY) === deltaX : ui.helper.data('draggableXY.xMax');
ui.helper.data('draggableXY.xMax', xMax);
var newPosition = ui.position;
if(xMax) {
newPosition.top = originalPosition.top;
}
if(!xMax){
newPosition.left = originalPosition.left;
}
return newPosition;
}
});
};
use the drag event to your advantage
$('.selector').draggable({
drag: function(event, ui) { ... }
});
i'm not 100% sure how, but inside here, you can do a check on the coordinates. as ~jack-laplante said, this is where you would compare. if the coordinates are closer to the x axis than the y, change the axis to x
//setter
$('.selector').draggable('option', 'axis', 'x');
if the other way around change it to y. this will get you a snapping motion to always have the item either on the x axis or the y axis (from the starting point). you'd have to do a check to leave the item wherever it is if the axis was say (x+n,y+n), but it would be pretty impressive if someone got more than a few pixels staying on the |x|=|y| line.
you didn't specify if the axes always remain where they originally started or if they change depending on where the draggable item is on drag start (like if you move it a little bit, then let go, and try to drag it some more). there's a start: and end: event too that could help you with that part.
what exactly are you trying to drag that can't go diagonal, but can go left, right, up, and down?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With