JQuery Draggable + Sortable - how to drag between two scrollable lists

I would like to have two lists: the available items and the selected items, in which the available items are assigned the selected items using drag and drop. I need the selected elements to be sortable but not accessible elements. The problem is that both lists can contain a significant number of elements and therefore must be scrollable.

Here is the jQuery that I have so far:

<script type="text/javascript"> $(function() { $( "#available > li" ).draggable({ revert: 'invalid', connectToSortable: '#selected', containment: '#drag_container' }); $( "#selected" ).sortable({ axis: 'y', placeholder: 'ui-state-highlight' }); }); </script> 

And the corresponding HTML:

  <div class="drag_container"> <ul id="available" class="drag_column draggable"> <li id="item1" class="ui-state-default"><span class="ui-icon ui-icon-arrow-4-diag"></span>Item 1</li> <li id="item2" class="ui-state-default"><span class="ui-icon ui-icon-arrow-4-diag"></span>Item 2</li> <li id="item3" class="ui-state-default"><span class="ui-icon ui-icon-arrow-4-diag"></span>Item 3</li> <li id="item4" class="ui-state-default"><span class="ui-icon ui-icon-arrow-4-diag"></span>Item 4</li> <li id="item5" class="ui-state-default"><span class="ui-icon ui-icon-arrow-4-diag"></span>Item 5</li> <li id="item6" class="ui-state-default"><span class="ui-icon ui-icon-arrow-4-diag"></span>Item 6</li> <li id="item9" class="ui-state-default"><span class="ui-icon ui-icon-arrow-4-diag"></span>Item 9</li> <li id="item10" class="ui-state-default"><span class="ui-icon ui-icon-arrow-4-diag"></span>Item 10</li> </ul> <ul id="selected" class="drag_column draggable sortable" style="margin-left: 20px;"> <li id="item7" class="ui-state-default"><span class="ui-icon ui-icon-arrow-4-diag"></span>Item 7</li> <li id="item8" class="ui-state-default"><span class="ui-icon ui-icon-arrow-4-diag"></span>Item 8</li> <li id="item9" class="ui-state-default"><span class="ui-icon ui-icon-arrow-4-diag"></span>Item 9</li> <li id="item10" class="ui-state-default"><span class="ui-icon ui-icon-arrow-4-diag"></span>Item 10</li> <li id="item11" class="ui-state-default"><span class="ui-icon ui-icon-arrow-4-diag"></span>Item 11</li> <li id="item12" class="ui-state-default"><span class="ui-icon ui-icon-arrow-4-diag"></span>Item 12</li> <li id="item13" class="ui-state-default"><span class="ui-icon ui-icon-arrow-4-diag"></span>Item 13</li> <li id="item14" class="ui-state-default"><span class="ui-icon ui-icon-arrow-4-diag"></span>Item 14</li> <li id="item15" class="ui-state-default"><span class="ui-icon ui-icon-arrow-4-diag"></span>Item 15</li> <li id="item16" class="ui-state-default"><span class="ui-icon ui-icon-arrow-4-diag"></span>Item 16</li> <li id="item17" class="ui-state-default"><span class="ui-icon ui-icon-arrow-4-diag"></span>Item 17</li> <li id="item18" class="ui-state-default"><span class="ui-icon ui-icon-arrow-4-diag"></span>Item 18</li> </ul> <div style="clear: both">&nbsp;</div> </div> 

However, with the requirement of a scrollable list, I cannot get the drag and drop behavior to work elegantly (see demo http://pastehtml.com/view/1bsk6bt.html ).

As soon as the dragged item is included in the list of available items, it disappears behind the scrollable frame. I tried the clone helper, and also tried playing with divs containing various overflow options, disabling the scroll option in jQuery, but I can't get it to work correctly. I'm sure someone out there did something like what I'm going to do here and can save some time? :)

Any help would be greatly appreciated!

+6
jquery jquery-ui jquery-ui-sortable jquery-ui-draggable
source share
2 answers

Phew! It was fun to fix.

The first problem, when the list scrolls forever horizontally, I fixed some simple overflow changes in your CSS. I removed both overflow attributes from your .drag_column and placed the overflow: hidden in .drag_container.

 .drag_container { width: 1000px; margin: 0 auto; position: relative; border: 1px solid black; position: relative; z-index: 1; overflow: hidden; } .drag_column { padding: 5px; width: 490px; height: 200px; float: left; position: relative; } 

Unfortunately, when I did this, he created a position error when you dragged your draggable from one list to another (it will shoot up, depending on which element of the list you selected). To fix this, I added the line "helper: clone" to your drag and drop function.

 $( "#available > li" ).draggable({ revert: 'invalid', connectToSortable: '#selected', containment: '#drag_container', helper: 'clone' }); 

Again this created an undesirable effect. The clone helper makes the original list never delete items. To fix this, I had to manually create a function that would delete the old item. What I did was add the start: function to your draggable object, which grabbed the identifier of the object and placed it in a variable. Then I created the droppable object of your # selected list and made the drop: function there. This drop function simply makes the slUUp (100) of the object with a match identifier. Note that I have a variable created when the script runs - this fixes the error in IE.

 var dragged = null; $(function() { $( "#available > li" ).draggable({ revert: 'invalid', connectToSortable: '#selected', containment: '#drag_container', helper: 'clone', start: function(ui, event) { dragged = $(this).attr('id'); } }); $( "#selected" ).droppable({ drop: function(event, ui) { var ident = "#" + dragged; $(ident).slideUp(100); } }); 

I posted the full HTML page at http://pastehtml.com/view/1by9nfd.html so you can play if you want. Hope this helps!

+6
source share

I need this functionality and found a way to do it

use appendTo: "body" and set it to absolute at startup. The element that is being dragged is added to the body and is alwayz the β€œtop” of the other elements, because its position is absent from the body.

 $( "#available > li" ).draggable({ revert: 'invalid', appendTo: 'body', helper: 'clone', connectToSortable: '#selected', containment: '#drag_container', start: function( event, ui ){ $(ui.helper).css('position', 'absolute'); //helper if you are using clone }, stop: function(event, ui){ $(ui.helper).css('position', 'relative'); // if you want } }); 

Hope this helps

+1
source share

All Articles