Reputation: 395
Update: Here is the final fiddle. Thanks Twisty. https://jsfiddle.net/natjkern/55n1Lg61/14/
Here is a mock up of my site http://jsfiddle.net/natjkern/pjq9wqLy/
On the right I have a fixed list of elements called #userList
. This element must be set to overflow: auto, as the number of user elements is variable. I then need to drag a copy into dropzone, which again can vary in size, so it's container must be also set to overflow auto. I need the container to auto scroll when dragged element is dragged to edge to allow user to place element anywhere in dropzone. So far my best idea is to append to body first to escape the original auto overflow container then append to #dropzone
on droppable({over:})
. But this isn't really working out. Any UI experts out there that can give me a hand?
Here is my code so far:
$(document).ready(function () {
$('.moveMe').draggable({
helper: "clone",
appendTo: 'body',
revert: 'invalid',
scroll: true,
});
$('#dropZone').droppable({
accept: '.moveMe',
//here is where my problem arrises
// I need #dropZoneCon to scroll to place
over: function (event, ui) {
ui.helper.draggable.detach().appendTo($(this));
$('#DropZone div').css('position','absolute');
ui.helper.draggable.draggable('option', 'containment', 'parent');
},
/* */
drop: function (event, ui) {
ui.helper.draggable.detach().appendTo($(this));
$('#DropZone div').css('position','absolute');
ui.helper.draggable.draggable('option', 'containment', 'parent');
},
});
});
Note: commenting out over: allow me to place element where I would like, but I really need the scrolling to work.
Upvotes: 1
Views: 313
Reputation: 30903
This is a little clunky, but it does what you're looking to do.
http://jsfiddle.net/Twisty/55n1Lg61/5/
JQuery
$(document).ready(function() {
var tEntered = false;
$('.moveMe').draggable({
helper: "clone",
appendTo: 'body',
revert: 'invalid',
drag: function(e, u) {
var curPos = u.offset;
var $target = $("#dropZoneCon");
var tVP = $target.offset();
var tW = Math.floor($target.width());
var tH = Math.floor($target.height());
var pad = 20;
var scrInc = 10;
var x0 = tVP.top;
var x1 = tVP.top + tH;
var y0 = tVP.left;
var y1 = tVP.left + tW;
$("#dragInfo").html("Over #dropZone: " + tEntered + ", top: " +
tVP.top + "/" + curPos.top + "/" + x1 + " left: " + tVP.left + "/" + curPos.left + "/" + y1);
if (tEntered) {
// Increase Scroll
if (curPos.left >= (y1 - pad) && curPos.left <= y1) {
$target.scrollLeft($target.scrollLeft() + scrInc);
}
if (curPos.top >= (x1 - pad) && curPos.top <= x1) {
$target.scrollTop($target.scrollTop() + scrInc);
}
// Decrease Scroll
if (curPos.left >= y0 && curPos.left <= (y0 + pad)) {
$target.scrollLeft($target.scrollLeft() - scrInc);
}
if (curPos.top >= x0 && curPos.top <= (x0 + pad)) {
$target.scrollTop($target.scrollTop() - scrInc);
}
}
}
});
$('#dropZone').droppable({
accept: '.moveMe',
over: function(e, u) {
tEntered = true;
},
out: function(e, u) {
tEntered = false;
},
drop: function(event, ui) {
ui.draggable.detach().appendTo($(this));
$('#DropZone div').css('position', 'absolute');
ui.draggable.draggable('option', 'containment', 'parent');
},
});
});
So we do a lot of the heavy lifting in the drag
event since we can determine the position of the drag object from this event. In the drag event we define a number of variables:
curPos
the current position of our draggable object in { top, left }
$target
the dropZone containertVP
the Target View Port offset in { top, left }
tW
& tH
the Target's Width and HeightscrInc
a value we will use to increase or decrease the scroll positionpad
the amount of pixels to use as the edge detection of tVP
x0
& x1
are the tVP
top edge and bottom edgey0
& y1
are the tVP
left edge and right edgeI defined tEntered
outside of these functions, so I can access it from either draggable or droppable. Since droppable has over
and out
, we can use those to change this value.
Now, when tEntered
is true, meaning we are dragging an object over the target, we look to see if the x
and y
might be within our padding. If they are we increase or decrease the scroll position.
I found this helpful: http://www.jqwidgets.com/community/topic/how-detect-area-dropped-inside-a-div-into-another-div/
This should allow you to do what you want unless I misunderstood. Comment if you have questions.
Upvotes: 1