I am currently trying to apply a "drag and drop" - functionality to a bunch of elements using jQuery and jQuery UI. It should be noted, that the elements should always snap to a specific grid when being dragged. I was very happy to see that in this question @Nate already explained the functionality very well. The problem I'm facing is, that the grid the draggable elements should snap to should be oriented to the droppable element AND the draggable elements are no children to the droppable element.
In detail, the draggable elements of varying sizes should always snap to a grid consisting of 40x40 cells oriented to a droppable (in my example 400x400, so a 10x10 grid), thats in another part of my html. The main problem i'm facing is, that i can't seem to get the orientation of my snapping grid to align with my droppable. Here's my current approach in javascript:
$(document).ready(function(){
$(".draggable").draggable({
revert: true,
revertDuration: 0,
snap: true,
snapTolerance: 40,
containment: ".container",
drag: function( event, ui ) {
var snapTolerance = $(this).draggable('option', 'snapTolerance');
//get positions of the own board and the currently dragged element relative to the document
var ownBoardPositionRelToDoc = $("#droppable").offset();
var uiPositionRelToDoc = ui.helper.offset();
var topDiffToDoc = ui.helper.offset().top - ui.position.top;
var leftDiffToDoc = ui.helper.offset().left - ui.position.left;
console.log(ownBoardPosition);
console.log(uiPosition);
topRemainder = ownBoardPosition.top % 40;
leftRemainder = ownBoardPosition.left % 40;
if (topRemainder <= snapTolerance) {
ui.position.top = ui.helper.offset().top - topRemainder;
}
if (leftRemainder <= snapTolerance) {
ui.position.left = ui.helper.offset().left - leftRemainder;
}
}
});
$(".droppable").droppable({
accept: ".draggable",
tolerance: "fit",
drop: function(event, ui) {
$(ui.draggable).appendTo($(this));
}
});
});
I've constructed a JSFiddle to explain my idea further. Sadly it's not executable due to JQuery UI not being supported but you should get the idea.
Consider the following.
JavaScript
$(function() {
$(".draggable").draggable({
revert: true,
revertDuration: 0,
containment: ".container",
grid: [40, 40]
});
$(".droppable").droppable({
accept: ".draggable",
tolerance: "fit",
drop: function(event, ui) {
$(ui.draggable).appendTo($(this));
}
});
});
https://jsfiddle.net/Twisty/rLx7jtob/
You can use grid
to make it easier.
https://api.jqueryui.com/draggable/#option-grid
Snaps the dragging helper to a grid, every x and y pixels. The array must be of the form
[ x, y ]
.