Draggables inside overflow:auto div

111 views
Skip to first unread message

Tof

unread,
Feb 22, 2009, 12:43:01 PM2/22/09
to Prototype & script.aculo.us
Hi,

I'm sure this question has already been asked, but all answers and/or
patches I've found don't work for me.
I have some draggables inside an overflow:auto div.
When I try to drag one element, I can't drag it outside the parent
div.

I'm using scriptaculous 1.8.1, but I don't see any change concerning
this problem in 1.8.2 Changelog.

Does anybody have a solution/patch ?

Thanks a lot.

Regards.

david

unread,
Feb 24, 2009, 5:58:52 AM2/24/09
to Prototype & script.aculo.us
Hi tof,

you draggables elements are contained inside parent, so when you try
to dragg them, they are still inside the parent contener :))
What you'll have to do is to use the ghost parameter that create a
clone of the element which don't belong to the parent contener.
Another way to do this is to create a callback on the "startDrag"
callback and detach element from it's parent, then clone it's position
to previous one. But with this method, you should reattach the element
when the "stopDrag" effect appear.

--
david

Tof

unread,
Feb 24, 2009, 7:00:47 AM2/24/09
to Prototype & script.aculo.us
Hi David,

Thanks for your answer.
Unfortunately, setting 'Ghosting' option to true doesn't change
anything.
I tried to apply the patch given in ticket #5771 (http://
dev.rubyonrails.org/ticket/5771), and now, it almost works.
I can drag my Draggable outside the overflowed div, but, it that div
has been scrolled, the cloned object don't have the right position,
behind the mouse.
There's an offset, I think, due to the offset of the original element
in the scrolled div.

How can I fix this ?
Thanks a lot.

Tof

unread,
Feb 24, 2009, 9:29:08 AM2/24/09
to Prototype & script.aculo.us
Ok, finally, I think I got it know.
For thoses who are interested, I use the "SubsDraggable" code found in
the ticket 5771, with some modifications (adapted to Prototype 1.6,
and :

// extentions for scriptaculous dragdrop.js
function getDragElement(element)
{
var el = element.cloneNode(true);
el.id = 'sub'+element.id;
el.style.position = 'relative';
document.body.appendChild(el);
return el;
}

var SubsDraggable = Class.create(Draggable, {
initialize: function($super, element) {
var options = arguments[2] || {};
$super(element,options);
if( typeof(this.options.dragelement) == 'undefined' )
this.options.dragelement = false;
},
initDrag: function(event) {
if(!Object.isUndefined(Draggable._dragging[this.element]) &&
Draggable._dragging[this.element]) return;
if(Event.isLeftClick(event)) {
// abort on form elements, fixes a Firefox issue
var src = Event.element(event);
if((tag_name = src.tagName.toUpperCase()) && (
tag_name=='INPUT' ||
tag_name=='SELECT' ||
tag_name=='OPTION' ||
tag_name=='BUTTON' ||
tag_name=='TEXTAREA')) return;

var pointer = [Event.pointerX(event), Event.pointerY(event)];
// HERE are my modifications to calculate the
new clone position. I'm not sure if there is an easier method, but
this one seems to work.
var pos = this.element.cumulativeOffset();
var scroll = this.element.cumulativeScrollOffset();
var vpscroll= document.viewport.getScrollOffsets();
this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]
+ scroll[i] - vpscroll[i] ) });

Draggables.activate(this);
Event.stop(event);
}
},
startDrag: function($super, event) {
if( this.options.dragelement ){
this._originalElement = this.element;
this.element = this.options.dragelement(this.element);
Position.absolutize(this.element);
Position.clone(this._originalElement, this.element);
}
$super(event);
},
finishDrag: function($super, event, success) {
$super(event, success);

if(this.options.dragelement){
Element.remove(this.element);
this.element = this._originalElement;
this._originalElement = null;
}
}
})

My draggables are now initialized like this :

new SubsDraggable('elementid', { dragElement: getDragElement, ...});

Regards,
Tof.
Reply all
Reply to author
Forward
0 new messages