How to Fix Wrongly Positioned Draggable Helpers for Connected Sortables (Partially Caused by Floated/Relative Positioned Parent Elements)

How to fix wrongly positioned draggable helpers for connected sortables (partially caused by floated/relative positioned parent elements)?

What is strange is that it seems to work better with jquery-ui 10.4. The difference is that in 10.4 the draggable helper stays in its original div, and is cloned into the sortables but hidden. So calculations are easier to make.

In 11.4, the helper is appended to the sortable over which it is dragged, which makes the precise offset calculations hard to follow. You constantly have to change the parent offset, and keep track of over which sortable it is, over which sortable it was, the position of the sortable and so on. And clearly there is a bug there.

One simple solution would be to get the connectToSortable plugin from 10.4. You'll have to check for unwanted side effects, but quickly it seems to be working. You can use a different name so that you keep the original. Like this:

$.ui.plugin.add("draggable", "connectToSortable104", {
// You take the whole connectToSortable plugin from
// here: https://code.jquery.com/ui/1.10.4/jquery-ui.js
// In 11.4 you'll need to add draggable parameter
// for example: to the event methods,
// start: function(event, ui, draggable)
...

See http://jsfiddle.net/gsnojkbc/2/

EDIT:

I don't think the additional div is what causes the problem, it's really a bug with the way the connectToSortable works in jquery 11.4 that is causing the issue. To allow moving the helper in the sortables and still keep track of the proper offset, you need to readjust some data each time the helper changes div. There's two flaws in the way it's done:

First one is that there's a refreshOffsets method that is common to
other events in draggable. It's used for example when you click on a
draggable. And so it tries to calculate the offset based on the
click. But when calling refreshOffsets from the sortable event, it
messes the click offset. This can be solved by changing
refreshOffsets method so as not to consider the event.pageX and Y.
Like this:

$.ui.draggable.prototype._refreshOffsetsSortable = function(event, draggable){

this.offset = {
top: this.positionAbs.top - this.margins.top,
left: this.positionAbs.left - this.margins.left,
scroll: false,
parent: this._getParentOffset(),
relative: this._getRelativeOffset()
};

this.offset.click = draggable.offset.click;
}

The other problem happens because you have many sortables. Basically
the other operation that needs to be done is change the parent
offset. The way it's done right now is that it saves the previous
parent. Normally it works but if you move too fast, the sequence
makes it so that the saved parent is a sortable and not the original
parent. You can fix this by saving the parent on drag start, which in
any case makes seems to make more sense. Like this:

$.ui.plugin.add( "draggable", "connectToSortableFixed", {
start: function( event, ui, draggable ) {
var uiSortable = $.extend( {}, ui, {
item: draggable.element
});
draggable._parent = this.parent();
...

See here: http://jsfiddle.net/24a8q49j/1/

Invalid mouse offset for cross-frame draggable + sortable

solution 2 update

I added this js function because when you add too many draggable element to the iframe, the drag elements can be overlapped by the sortable elements if you scroll down

$('.draggable').on('dragstop',autoResize);

function autoResize(){
var newheight;
if(document.getElementById){
newheight=document.getElementById('my-frame').contentWindow.document .body.scrollHeight;
}
newheight=newheight+100;
$('#my-frame').css('height',newheight);
}

here the new jsfiddle

end solution 2 update

This problem appear to be a bug and someone have made his solution ( basically a workaround): trasparent div solution

1
My first solution, without changing the code, could be in placing the iframe before of the draggable stuff, as shown here, the code:

<iframe id="my-frame" src="/VqxGf/3/show"></iframe>
<ul>
<li class="draggable">Drag me</li>
<li class="draggable">Drag me 2</li>
<li class="draggable">Drag me 3</li>
</ul>

2
Another solution that seems to work is to play with the style property: position absolute for the ul in which contain the draggable

  • s, a bit of margin-top for the sortable stuff in the frame and, maybe, a frameborder=0. jsfiddle
    The main page:

    <ul style="position:absolute">
    <li class="draggable">Drag me</li>
    <li class="draggable">Drag me 2</li>
    <li class="draggable">Drag me 3</li>
    </ul>
    <iframe frameborder="0" id="my-frame" src="/ATu6F/30/show"></iframe>

    The iframe page:

    <ul id="sortable" style="margin-top:100px" class="sortable idle">
    <li>Sortable</li>
    <li>Sortable 2</li>
    <li>Sortable 3</li>
    </ul>

    <ul id="sortable2" class="sortable idle">
    <li>Sortable</li>
    <li>Sortable 2</li>
    <li>Sortable 3</li>
    </ul>

    Hope this helps.

    Please see the edit at the beginning of this post

    Jquery UI Draggable Absolute Instead of Relative?

    Why doesn't position:absolute work for you?

    Since absolutely positioned elements are no longer part of the document flow, each of your three <div>s are placed at 0,0 of its containing (positioned) element. Thus, it's up to you to work out the starting position of your draggables.

    Storing Sortables in localStorage

    Your for loop is using one of the values for the starting index rather than the actual length of the array, the correct for loop header should be as follows.

    for (var i = arrValuesForOrder.length - 1; i >= 0; i--) {


    Related Topics



  • Leave a reply



    Submit