It looks like that the 'grid' option in the constructor of Draggable is relatively bound to the original coordinates of the element being dragged - so simply put, if you have three draggable divs with their top set respectively to 100, 200, 254 pixels relative to their parent:
<div class="parent-div" style="position: relative;">
<div id="div1" class="draggable" style="top: 100px; position: absolute;"></div>
<div id="div2" class="draggable" style="top: 200px; position: absolute;"></div>
<div id="div3" class="draggable" style="top: 254px; position: absolute;"></div>
</div>
Adn all of them are getting enabled for dragging with 'grid' set to [1, 100]:
draggables = $('.draggable');
$.each(draggables, function(index, elem) {
$(elem).draggable({
containment: $('#parent-div'),
opacity: 0.7,
revert: 'invalid',
revertDuration: 300,
grid: [1, 100],
refreshPositions: true
});
});
Problem here is that as soon as you drag div3, say, down, it's top is increased by 100, moving it to 354px instead of being increased by just mere 46px (254 + 46 = 300), which would get it to the next stop in the grid - 300px, if we are looking at the parent-div as a point of reference and "grid holder".
I had a look at the draggable sources and it seem to be an in-built flaw - they just do all the calculations relative to the original position of the draggable element.
I would like to avoid monkey-patching the code of draggable library and what I am really looking for here is the way how to make the Draggable calculate the grid positions relative to containing parent. However if monkey-patching is unavoidable, I guess I'll have to live with it.
Jquery Desktop:
I've started using JQuery draggable over the last couple of days and found an easy fix to this.
Set the position property to absolute and add your widgets with top and left set to values that line up to your grid.
As the values for top/left are absolute they also make more sense when going off and storing them in a db.
I got around this problem by simply adding my own script to drag: under draggable and setting it to divide math.Floor(x/100)*100 and the same for Y.
If you don't mind poking around in source look at
http://labs.pezcuckow.com/solveit/game.htmland the make draggable function! (game nonwhere near finished)you'll also find a problem with revert, it doesn't put them back snapped to grid. So I wrote my own "check if invalid" function in end: of dragabble (again viewable on the game above).
Since @Pez's answer is lost (404), here's how I did it:
Demo: http://jsfiddle.net/ThiefMaster/yGsSE/