Make roaming element sortable in droppable using jQuery UI

RESOLVED

So, I studied sortable() with the connectWith attribute a little more and found that the solution was simpler than I expected, but I thought about it in the opposite direction due to draggable() and droppable() .

Here's the fiddle: http://jsfiddle.net/DKBU9/12/


The original question follows:

This is an extension of the previous SO question, which I felt should be kept separate.

The original subject: jQuery UI - Clone droppable / sortable list after drop event . It considers reinitializing a droppable handler on cloned elements.

Also, I'm trying to allow items that have been dragged from the original list to be sorted in redirected lists.

Here is a fiddle essentially illustrating the current behavior as a result of the original question: http://jsfiddle.net/DKBU9/7/

And the required code, because SO likes to complain and inflate these messages:

HTML

 <ul id="draggables"> <li>foo1</li> <li>foo2</li> <li>foo3</li> </ul> <ul class="droppable new"> </ul> 

Js

 $(function() { $('#draggables > li').draggable({ appendTo: 'document', revert: 'invalid' }); $('.droppable > li').draggable({ appendTo: 'document', revert: 'invalid' }); $('#draggables').droppable({ accept: '.droppable > li', drop: function(event, ui) { ui.draggable.detach().css({top: 0,left: 0}).appendTo($(this)); cleanUp(); } }); initDrop($('.droppable')); }); function initDrop($element) { $element.droppable({ accept: function(event, ui) { return true; }, drop: function(event, ui) { if($(this).hasClass('new')) { var clone = $(this).clone(); $(this).after(clone); $(this).removeClass('new'); initDrop( clone ); } ui.draggable.detach().css({top: 0,left: 0}).appendTo($(this)); cleanUp(); } }).sortable({ items: 'li', revert: false, update: function() { cleanUp(); } }); } function cleanUp() { $('.droppable').not('.new').each(function() { if($(this).find('li').length == 0) { $(this).remove(); } }); } 

Help question: JQuery UI combines sorting and drag & drop

I am trying to use this SO question to solve my problem, since the result is exactly what I am trying to achieve, in particular, the last fiddle contained in the comments of the accepted answer, but I cannot seem to figure out how to adapt it to my code taking into account minor differences. For example, the fiddle in this question clones the item being dragged, rather than dragging the actual item and, unlike mine, does not allow dragging items to the original list.

Therefore, any help to try to get this result for my code would be greatly appreciated.

In addition, in this example, the accept attribute is set as a function to return true. What is the reason for this? Doesn’t this mean that he will accept something or some dragged item?

EDIT: I read a couple of answers that just used sortable () with the connectWith attribute, but for some reason I didn't think it did what I needed, partly because I didn't want the original list to be sorted also. However, using only sortable (), it seems that I got the functionality, but I have not adapted all the event handlers yet.

+7
jquery jquery-ui jquery-ui-sortable jquery-ui-droppable jquery-ui-draggable
source share
1 answer

See this fiddle .

This will cause the items to be discarded and sorted in the new lists, but not in the original (according to your editing).

There are several tricks:

1) Starting with draggable, I added a new function because we need to leave a placeholder (use the clone) so that the containers do not jump while dragging and we need to initialize the new element as draggable.

 function initDraggable($element) { $($element).draggable({ connectToSortable: '.droppable', revert: function(droppableObj) { if(droppableObj === false) { $(this).removeClass('dragging'); return true; } else { return false; } }, helper: 'clone', start: function(e, ui) { $draggingParent = $(this).parent(); $(this).addClass('dragging'); } }); } 

Pay attention to connectToSortable: using .droppable (as a cleanup, I think you should change droppable to sort);

Note also revert: - this gives us the ability to remove the drag and drop class (which makes the invisible element (cloned) invisible) when returning.

Finally, there is start , which adds the 'dragging' class, which makes the original (cloned) element invisible during drag and drop. It also sets $ draggingParent, which is used to check if an item is being dragged from #draggables or .droppables .

2) Then for #draggables there is droppable() :

  $("#draggables").droppable({ drop: function(ev, ui) { if($draggingParent[0] === $(ui.helper).parent()[0]) { //dragged from draggables to draggables $(ui.draggable).removeClass('dragging'); } else { if(ui.draggable.parent()) var $clone = $(ui.draggable).clone(); $(ui.draggable).remove(); $clone.removeClass(); $clone.removeAttr('style'); initDraggable($clone); $(this).append($clone); } } 

Note that the drop handler checks to see if this item is removed from #draggables or .droppables and acts accordingly.

3) Finally, as you already mentioned, we really want droppable to be sortable:

 function initDroppableSort($element) { $element.sortable({ items: 'li', connectWith: ".droppable,#draggables", revert: true, stop: function(event, ui) { $(ui.item).removeClass('dragging'); $('.dragging').remove(); if($(this).hasClass('new')) { var clone = $(this).clone(); clone.empty(); $(this).after(clone); $(this).removeClass('new'); initDroppableSort( clone ); } cleanUp(); } }); } 

Pay attention to connectWith and, in particular, to the fact that it applies to both .droppable and #draggables .

+4
source share

All Articles