I\'m trying to make a list of elements which can be repositioned by dragging and dropping. The first element, Box 1, works just fine 100% of the time. Sometimes the second b
change this function
function addDropSpaces()
{
$(this).after('<div class="empty-drop-target"></div>');
}
in your version you are adding that div after each of the $questionItems.
Not sure whether it is a bug or not, but I think the problem comes in when you change the DOM in the dragstart handler. The reason the first box works I presume has something to do with the fact that its position is before the other boxes in the DOM and when you change the DOM, the position (?) of the first one isn't affected and the dragdrop events fire reliably.
You will need to refactor your code somewhat, and add the dropSpaces in the dragenter event handler. You would need to change your addDropSpaces method to accommodate the fact that it will be called multiple times, though.
Had this problem just now - it is a Chrome bug, you must not manipulate the DOM in dragStart event, or else dragEnd fires immediately. The solution for me turned out to be - use setTimeout() and manipulate the DOM inside the function you timeout.
It seems to be a Chrome bug : https://groups.google.com/a/chromium.org/forum/?fromgroups=#!msg/chromium-bugs/YHs3orFC8Dc/ryT25b7J-NwJ
Life is easier with jQuery. This is exactly what you described you wanted, using jQueryUI.
http://jqueryui.com/draggable/#sortable
which allows sorting. The code:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>jQuery UI Draggable + Sortable</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.8.3.js"></script>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
<style>
ul { list-style-type: none; margin: 0; padding: 0; margin-bottom: 10px; }
li { margin: 5px; padding: 5px; width: 150px; }
</style>
<script>
$(function() {
$( "#sortable" ).sortable({
revert: true
});
$( "#draggable" ).draggable({
connectToSortable: "#sortable",
helper: "clone",
revert: "invalid"
});
$( "ul, li" ).disableSelection();
});
</script>
</head>
<body>
<ul>
<li id="draggable" class="ui-state-highlight">Drag me down</li>
</ul>
<ul id="sortable">
<li class="ui-state-default">Item 1</li>
<li class="ui-state-default">Item 2</li>
<li class="ui-state-default">Item 3</li>
<li class="ui-state-default">Item 4</li>
<li class="ui-state-default">Item 5</li>
</ul>
</body>
</html>
also see: http://jqueryui.com/sortable/
Try adding the events manually, the long way, something like :
$questionItems[0].on('dragstart', startDrag);
$questionItems[0].on('dragend', removeDropSpaces)
$questionItems[0].on('dragenter', toggleDropStyles)
$questionItems[0].on('dragleave', toggleDropStyles);
$questionItems[1].on('dragstart', startDrag);
$questionItems[1].on('dragend', removeDropSpaces)
$questionItems[1].on('dragenter', toggleDropStyles)
$questionItems[1].on('dragleave', toggleDropStyles);
etc. just to see the effect?
You need to prevent the "event" from bubbling up so it doesn't fire up other events. See https://developer.mozilla.org/en-US/docs/DOM/event.stopPropagation
For startDrag, toggleDropStyles, removeDropSpaces functions, you'd write something like this:
function startDrag(ev) {
ev.stopPropagation();
... your code here ...
}