JQuery UI Draggable with hidden Droppable

744 views Asked by At

I have a list of draggable elements, that I wish to drop into various containers. The droppable containers are listed inside collapsable divs, because there are quite a lot of them.

In short, the droppable structure looks like this: Sliding container > Multiple droppables (hidden inside sliding container)

When I drag an element onto the sliding container, it triggers the slideDown()-method (meaning that the container itself is technically also a droppable, using the hover-option). This reveals all the droppables inside, and I can drop my element where I want it.

This part works perfectly.

The problem is somewhat strange, but yet consistent in pretty much all browsers. I have multiple of these sliding containers stacked on top of each other. When a container is sliding to open, it will push other containers down on the page - or at least, that is what I see. However, when I continue to drag my elements around, it is like some kind of "ghost" is left behind by the containers that were pushed down. When I move my draggable element into the spot where one of these "pushed" containers used to be, it will still trigger its own slideDown(), even though I am not really touching it.

Of course, this is not a problem for the container that is at the bottom of the stack, since it is not pushing any other containers away when it opens. All the other ones have this "ghost"-problem.

The only solution is to drag the element onto the container I want, and let it expand. I then pull my element aside, making sure I don't touch the stack of containers. I drag it all the way to the bottom of the page, to trigger a window scroll event. Once the window scrolls, the elements are somehow "refreshed" and all these ghost containers disappear.

This tells me the problem has to do with redrawing or repainting. I have tried various methods of triggering this effect in code, but it only seems to happen when I drag an element to the bottom of the page. If I use arrow keys, page down og the mouse scroll it does not work.

Do you have any suggestions?

Like I pointed out, the same problem occurs in all major browsers, so it is most likely a design flaw in JQuery UI that is causing this behaviour.

TLDR; The droppable targets don't refresh/redraw/update while I'm dragging an element around, even if the droppable element itself is moved (and I keep on dragging). It only updates when I drag to the very bottom of the page to trigger a scroll, or if I let the draggable element go and pick it back up again.

UPDATE:

Here's some sample code: https://jsfiddle.net/n6hu7vah/

<html><head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
</head><body>

<div class="row">
    <div class="container">Drag the box over the upper container.<br />Drag downwards, and watch how the other containers react before you even touch them.<br />(Tested in Chrome)<br /><br /></div>
</div>
<div class="row">
    <div class="col-xs-6" id="left"></div>
    <div class="col-xs-6" id="right"></div>
</div>

<script>

// A draggable element

var e = $(document.createElement("div")).attr("class", "alert alert-danger pull-left").css("position", "absolute").css("white-space", "nowrap").css("z-index", "1051").html("Drag me!");
e.draggable({});
$("#left").append(e);



// Some droppable containers that slide out

var p = $(document.createElement("div")).attr("class", "panel panel-primary");
var h = $(document.createElement("div")).attr("class", "panel-heading").html("<h3 class=\"panel-title\">Title</h3>");
var b = $(document.createElement("div")).attr("class", "panel-body").html("<p>Lots<p>of<p>content");

p.append(h);
p.append(b);

$("#right").append(p.clone());
$("#right").append(p.clone());
$("#right").append(p.clone());
$("#right").append(p);

$("div.panel-heading").droppable({
    over: function() {
        $(this).parent().children("div.panel-body").slideDown();
    }
});
$("div.panel-body").hide();
</script></body></html>
0

There are 0 answers