JSFiddle - React, Tailwind, and code Playground
HTML
<p>Multi-select Drag</p>
<p>
<kbd>Click</kbd> to select individual items<br />
<kbd>Ctrl + Click</kbd> to select multiple items
</p>
<br />
<ul>
<li data-label-t="one">One</li>
<li data-label-t="two">Two</li>
<li data-label-t="three">Three</li>
<li data-label-t="4"></li>
<li data-label-t="5">5</li>
<li data-label-t="6">6</li>
<li data-label-t="7">7</li>
<li data-label-t="8">8</li>
<li data-label-t="9">9</li>
<li data-label-t="10">10</li>
</ul>
<ul>
<li data-label-t="Four">Four</li>
<li data-label-t="Five">Five</li>
<li data-label-t="Six">Six</li>
</ul>
<ul>
</ul>
CSS
ul {
border:1px solid Black;
width:200px;
height:200px;
display:inline-block;
vertical-align:top
}
li {
background-color:Azure;
border-bottom:1px dotted Gray
}
li.selected {
background-color:GoldenRod
}
JavaScript
/*
* Base on the following snippet : https://stackoverflow.com/a/15301704
*/
$("ul").on('click', 'li', function(e) {
if ((e.ctrlKey || e.metaKey)) {
var $this = $(this);
// Multiselection : check the selected item has the same parent
// of the alreay selected items
var $selectedItems = $('ul .selected');
var $firstSelectedItem = $selectedItems.first();
if ($firstSelectedItem.length === 0
// Multiselection : check the selected item has the same parent of the alreay selected items
||
$firstSelectedItem.siblings().is($this)
// Multiselection : unselect the current item only if there is at least 1 selected item.
// There must always be 1 selected item
||
(this === $firstSelectedItem.get(0) && $selectedItems.length > 1)) {
$this.toggleClass("selected");
}
} else {
// Singleselection : unselect previous selected items
$('ul .selected').removeClass('selected');
$(this).addClass("selected");
}
}).sortable({
connectWith: "ul",
delay: 150, //Needed to prevent accidental drag when trying to select
revert: 0,
helper: function(e, item) {
//Basically, if you grab an unhighlighted item to drag, it will deselect (unhighlight) everything else
if (!item.hasClass('selected')) {
item.addClass('selected').siblings().removeClass('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('.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('.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...