This project is read-only.
3

Resolved

Dragged item bad positioned when using UI.Layout

description

I use UI.Layout plugin to layout the page (top header, left menu, rest content). When I use the List DragSort for a list inside a UI.Layout content pane, the dragged item is bad positioned. It has an offset equal to the top left position of the UI.Layout pane. I'm testing with IE7, jquery 1.3.2, dragsort 0.3, ui.layout 1.2.0.
 
I have examined the plugin code, and I think the problem is caused because the list.draggedItem is positioned absolute inside a div already positioned absolute. The top, left css styles are not relative to the document, but to the parent absolute div. The offset() function is not 100% compatible with css({top:y,left:x}) when ancestor absolute divs are in play.
 
I have found a solution for me: substract the position of the absolute containers. My patch is adding this piece of code just before the last statement of the setPos function:
 
this.draggedItem.parents().each(function(){
    if (this.style.position == "absolute") {
        var offset = $(this).offset();
        top -= offset.top;
        left -= offset.left;
    }
});

comments

carrasco wrote Sep 7, 2009 at 1:37 PM

Had the same problem and this post almost fixed it. Only in my case the parent container was positioned "relative" and this.style.position somehow didn't work either.
So I changed the if-condition to

if( $(this).css( "position" ) == "absolute" || $(this).css( "position" ) == "relative" )

Else (and with the fix provided here) it's working smoothly. Great work!

wirthmi wrote Oct 29, 2009 at 5:43 PM

Thanks both of you. I had the same problem except that my list of items was inside 2 elements with css position setted to relative. Your solution didn't work for me. The reason is that CSS top & left values for position absolute or relative are little bit different from jquery's offset() function. This function return offset related to the whole document (doesn't matter how deep the element is and how many relative/absolute parents it has). On the other hand CSS define top & left relatively to the closest relative/absolute ancestor. Often it is of course body element. In such case the jquery's offset() and CSS top & left give equal results. Bocca's patch doesn't reflect this. I made a small improvement. There is no need to subtract all parents. Subtraction of the first absolute / relative element is sufficient. So following patch placed right before last statement of setPos function works great for me.

this.draggedItem.parents().each(function() {
if (($(this).css("position") == "absolute") || ($(this).css("position") == "relative")) {
    var offset = $(this).offset();
    top -= offset.top;
    left -= offset.left;
    return false;
}
});

mcm_ham wrote Nov 6, 2009 at 2:29 AM

Sorry I didn't see this earlier (I only had discussion notifications turned on and not issues). Thanks for posting your patches to this issue. I will release an update soon that includes this fix and a change to allow the empty placeholder to be styled.

mcm_ham wrote Feb 25, 2012 at 11:08 AM

Fixed in 0.3.7.


** Closed by mcm_ham 11/14/2009 8:27 PM

mcm_ham wrote Feb 25, 2012 at 11:08 AM