Scenario: Drag one or more elements and drop them in another list, but do not remove dragged elements from source list.
To allow for multiple dragging, I have used the code posted by Aaron Blenkush here.
I have made changes to fit my needs, like fixing the Shift issue.
$("ul").on('click', 'li', function (e) {
if (e.ctrlKey || e.metaKey) { //meta key for mac users
$(this).toggleClass("ui-selected");
$(this).parent().parent().siblings().children('ul').children().removeClass('ui-selected');
}
else if (e.shiftKey) {
// $(this).toggleClass("selected");
var list = $(this).parent();
var first = list.find('.ui-selected').first().index();
// var last = list.find('.selected').last().index();
var last = $(this).index();
if (first == -1 || last == -1) {
return false;
}
if (last < first) {
firstHolder = first;
first = last;
last = firstHolder;
}
for (i = first; i <= last ; i++) {
list.children().eq(i).addClass("ui-selected");
}
}
else {
$(this).addClass("ui-selected").siblings().removeClass('ui-selected'); //select only clicked element and unselecting other elements
//to Remove selected Class from 2nd UL li
$(this).parent().parent().siblings().children('ul').children().removeClass('ui-selected');
}
})
.sortable({
connectWith: "ul",
delay: 150, //Needed to prevent accidental drag when trying to select
revert: 0,
cursor: "move",
disabled: false,
placeholder: 'placeholder',
// handle: ".handle",
helper: function (e, item) {
//Basically, if you grab an unhighlighted item to drag, it will deselect (unhighlight) everything else
if (!item.hasClass('ui-selected')) {
item.addClass('ui-selected').siblings().removeClass('ui-selected');
}
//////////////////////////////////////////////////////////////////////
//HERE'S HOW TO PASS THE SELECTED ITEMS TO THE `stop()` FUNCTION:
//Clone the selected items into an array
var elements = item.parent().children('.ui-selected').clone();
//Add a property to `item` called 'multidrag` that contains the selected items, then remove the selected items from the source list
item.data('multidrag', elements)
//.siblings('.ui-selected').remove();
//Now the selected items exist in memory, attached to the `item`, so we can access them later when we get to the `stop()` callback
//Create the helper
var helper = $('<li/>');
return helper.append(elements);
},
start: function(event, ui) {
//$(ui.item).show();
var elements = ui.item.data('multidrag');
ui.item.after(elements);
//clone = $(ui.item).clone();
//before = $(ui.item).prev();
},
stop: function (e, ui) {
//Now we access those items that we stored in `item`s data!
var elements = ui.item.data('multidrag');
//`elements` now contains the originally selected items from the source list (the dragged items)!!
//Finally I insert the selected items after the `item`, then remove the `item`, since item is a duplicate of one of the selected items.
ui.item.after(elements).remove();
// $(ui.item).show();
//$(this).sortable('cancel');
}
});
Issue: It removes the dropped element from the source list.
I have researched a bit on this issue. Some say to use a clone in the helper method, but when I pass to a function that returns multiple elements I can't use clone. In Firebug when I drag elements it puts style=display:none on them but when I drop elements it removes them from the source list.
Update
i have made some changes in accepted answer to make it simpler
there are some issues like when li dropped from 1st list to 2nd list. and you drag back that li from 2nd to first it will remove element
solution cld be when item gets dropped in to 2nd list remove ui-selected class.
i hope it will help some one :)