I actually use gridster for drag some items.
My container is bigger than my window, so, i have a scrollbar on the right side, as usual. Now, if i want to drag an item from the top to the bottom, I need to click on it and scroll the mouse at the same time.
As you can see on this fiddle, If you take the item and you start to scroll, the item stay at his first position, you need to move the mouse for bring it to it.
There is a way for keep the item under the mouse even if you scroll ?
Sample html code:
<div class="container">
<div class="gridster">
<ul>
<li data-row="1" data-col="1" data-sizex="2" data-sizey="2">0</li>
<li data-row="1" data-col="3" data-sizex="1" data-sizey="2">1</li>
<li data-row="1" data-col="4" data-sizex="1" data-sizey="1">2</li>
<li data-row="3" data-col="2" data-sizex="3" data-sizey="1">3</li>
<li data-row="4" data-col="1" data-sizex="1" data-sizey="1">4</li>
<li data-row="3" data-col="1" data-sizex="1" data-sizey="1">5</li>
<li data-row="4" data-col="2" data-sizex="1" data-sizey="1">6</li>
<li data-row="5" data-col="2" data-sizex="1" data-sizey="1">7</li>
<li data-row="4" data-col="4" data-sizex="1" data-sizey="1">8</li>
<li data-row="1" data-col="5" data-sizex="1" data-sizey="3">9</li>
</ul>
</div>
</div>
Sample css code:
.container{
height:1600px;
}
Sample jQuery code:
var gridster;
$(function(){
gridster = $(".gridster ul").gridster({
widget_base_dimensions: [100, 55],
widget_margins: [5, 5],
}).data('gridster');
});
I guess defined as an algorithm, we want the draggable object, when we scroll, to stay where the mouse is. So we'd need an onScroll event somewhere.
Normally, we'd just update the position of the object with the position of the mouse, but onScroll doesn't seem to have mouse position information attached to it. Rephrasing it, we could say that we want the object to move/offset by n amount equal to the amount we scroll. That could work.
Of course some poking around gridster is needed to figure out how to offset the object. But I think something like this could work:
var gridster = $(".gridster ul").gridster({
widget_base_dimensions: [100, 55],
widget_margins: [5, 5],
draggable: {
start: function (e, ui, $widget) {
var that = this , //to access gridster from inside onscroll
oldScroll = $(document).scrollTop() //to calculate scroll change
obj = $(this.helper ? this.$helper : this.$player) //draggable/helper
$(document).on("scroll", function () {
//calculate scroll change
var curr = $(document).scrollTop()
var diff = curr-oldScroll
oldScroll = curr
//add change to stored offset for gridster
that.drag_api.el_init_offset.top += diff
//show change temporarily because gridster doesn't update
obj.css({
'top': parseFloat(obj.css("top")) + diff
});
})
},
stop: function (e, ui, $widget) {
$(document).off("scroll")
}
}
}).data('gridster');
Example
I guess this will be a good starting point. Current caveats, the grid itself doesn't update until another mousemove. Might need more poking about.
Update
The above code breaks on drag scroll as gridster has it's own scrolling implementation. Looking at the problem I couldn't find a way to differentiate between drag scroll and normal scroll (looked at onMouseWheel
and DOMMouseScroll
but didn't look like it was well supported. So I suppose a quick fix would be to disable offsetting on scroll if near the edge. So adding these:
//change stored offset for gridster if not on edge
if(!that.edge) that.drag_api.el_init_offset.top += diff
And we need to check on drag. So we add a drag handler to gridster. Something like:
drag:function(e,ui,$widget){
//check if edge
var pixelFromEdge=100
this.edge= e.clientY< pixelFromEdge ||
$("html")[0].clientHeight-e.clientY < pixelFromEdge
},
Demo
Honestly it feels there's probably a better and more elegant solution (short of actually modifying the plugin. which would probably be a lot easier)
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