Reputation: 154664
Using jQuery UI draggable/droppable, how can force multiple drop containers to scroll when the draggable is dragged over them?
For example, how can I make these "drop target" lists scroll when dragging the "drag me" square over them?
Fiddle of above: http://jsfiddle.net/AdrkG/
Note: the draggable({ scroll: true })
option will not work here, as the draggable isn't a child of either drop container.
And some code examples to satisfy StackOverflow (otherwise it complains that I'm only linking to JSFiddle):
<div class="draggable">drag me</div>
<div class="dropcontainer">
<div class="droppable">drop target 0</div>
<div class="droppable">drop target 1</div>
…
</div>
<div class="dropcontainer">
<div class="droppable">drop target 0</div>
<div class="droppable">drop target 1</div>
…
</div>
<script>
$(".draggable").draggable()
$(".doppable").droppable()
</script>
<style>
.dropcontainer {
overflow: auto;
width: 150px;
height: 100px;
}
</style>
Upvotes: 3
Views: 1433
Reputation: 8860
I have almost th the same problem now. Thanks @Bali Balo for the direction and great example. I just want to show 2-dimentional scroll variant of his code if somebody else needs:
var dropContainers = $(".dropContainer");
drag: function (event, ui) {
dropContainers.each(function () {
var $this = $(this);
var cOffset = $this.offset();
var bottomPos = cOffset.top + $this.height();
var rightPos = cOffset.left + $this.width();
clearInterval($this.data('timerScroll'));
$this.data('timerScroll', false);
if (event.pageX >= cOffset.left && event.pageX <= cOffset.left + $this.width()) {
if (event.pageY >= bottomPos - triggerZone && event.pageY <= bottomPos) {
var moveDown = function () {
$this.scrollTop($this.scrollTop() + scrollSpeed);
};
$this.data('timerScroll', setInterval(moveDown, 10));
moveDown();
}
if (event.pageY >= cOffset.top && event.pageY <= cOffset.top + triggerZone) {
var moveUp = function () {
$this.scrollTop($this.scrollTop() - scrollSpeed);
};
$this.data('timerScroll', setInterval(moveUp, 10));
moveUp();
}
}
if (event.pageY >= cOffset.top && event.pageY <= cOffset.top + $this.height()) {
if (event.pageX >= rightPos - triggerZone && event.pageX <= rightPos) {
var moveRight = function () {
$this.scrollLeft($this.scrollLeft() + scrollSpeed);
};
$this.data('timerScroll', setInterval(moveRight, 10));
moveRight();
}
if (event.pageX >= cOffset.left && event.pageX <= cOffset.left + triggerZone) {
var moveLeft = function () {
$this.scrollLeft($this.scrollLeft() - scrollSpeed);
};
$this.data('timerScroll', setInterval(moveLeft, 10));
moveLeft();
}
}
});
},
I added optimization not to search the droppable areas on every drag event - I pre-calculated it before initializing draggable widget. That substantially increased performance and responsiveness of dragging.
One more minor change is that it looks like moveUp and moveDown function names were interchanged ocasionally (I renamed them vise versa).
Upvotes: 2
Reputation: 3408
You may use the drag
event.
Here is an exemple: http://jsfiddle.net/AdrkG/8/
Upvotes: 4