Refresh jQuery UI Droppable Area After Shifting Position
I’ve recently been adding drag and drop functionality, using jQuery UI’s draggable and droppable interactions, to a website with a potentially large number of listings on each page. In order to provide a good user experience it was decided that the drop area should be moved when a drag operation starts so our users aren’t left dangling the draggable at the top of the page as it slowly scrolls upwards to the drop area.
This worked great from a UI and UX perspective, but given that the drag and drop was initialized with the drop area at the top of the page the drop only worked properly if the top of the drop area lined up with the top of the drop receiver [Fig. 1]. Shifting the drop area after the fact left the drop receiver unaltered, causing it to appear inactive [Fig. 2]. Or worse, if the shift was minimal, the drop area would overlap the drop receiver in an incorrect area and cause improper results (if there are a number of distinct listeners in the drop receiver area.) [Fig. 3]

An attempt to destroy and re-initialize the drop zone using both $(droppables).droppable('disable');$(droppables).droppable('enable'); and $(droppables).droppable('destroy');$(droppables).droppable(); did not have the desired effect – the position of the drop receiver had not been refreshed.
An option would be to use refreshPositions on a draggable object, but refreshing the positions on every mouse move would be a little much. However, peeking under the hood in refreshPositions reveals a $.ui.ddmanager.prepareOffsets function that takes two parameters. The first is either a collection of elements returned by a jQuery selector (ones already initialized for dragging) or a set of elements internal to the drag and drop plug-ins. Since the function is called externally, we’ll make use of the former:
$('.drag-elt').draggble({
start: function(e, ui) {
$.ui.ddmanager.prepareOffsets(
$(e.target).data('draggable'), e
);
}
});