Reputation: 29557
I have two sortable lists, A and B, created with Jquery's Sortable.
This is what I need:
Items that started out in list A should be sortable (also back and forth) between Lists A and B. However, items that started out in List B should never be moved to List A.
<ul id="sortable1" class="connectedSortable">
<li class="ui-state-default">A: Item 1</li>
<li class="ui-state-default">A: Item 2</li>
</ul>
<ul id="sortable2" class="connectedSortable">
<li class="ui-state-highlight">B: Item 1</li>
<li class="ui-state-highlight">B: Item 2</li>
</ul>
$(function() {
$( "#sortable1, #sortable2" ).sortable({
connectWith: ".connectedSortable"
}).disableSelection();
});
Upvotes: 1
Views: 435
Reputation: 5104
The following example is separated into two main parts: identifying the origin of each draggable element and checking if the drop is allowed.
First, we need to identify the origin from each element that will be dragged. The origin, in this case, was the id
attribute of the list that first contained the element. The value is going to be stored in an attribute called data-origin
.
$('.connectedSortable').find('li').attr('data-origin', function () {
var $parent = $(this).parents('ul');
return '#' + $parent.attr('id');
});
You can use the receive
event to implement the algorithmn that will verify if the element is allowed to be dropped in the list.
To cancel the drop, simple call the method .cancel()
.
In order to make the example more generic, i´ve created an additional attribute data-allow-from
in each list that indicates from which other lists it can receive elements.
Then we just create a simple callback function that will be invoked on the receive
event of each list, that gets the origin of the dropped element and check if it's in the allowed list.
function onReceive(event, ui) {
var receiver = $(event.target),
allowFrom = receiver.data('allow-from').split(',');
var origin = $(ui.item).data('origin');
var isAllowed = false;
allowFrom.forEach(function(element) {
if (element === origin) {
isAllowed = true;
return;
}
});
if (!isAllowed) {
$(ui.sender).sortable("cancel");
}
}
$(function() {
var opts = {
connectWith: ".connectedSortable",
receive: onReceive
};
$('.connectedSortable').sortable(opts).disableSelection();
$('.connectedSortable').find('li').attr('data-origin', function() {
var $parent = $(this).parents('ul');
return '#' + $parent.attr('id');
});
});
.connectedSortable {
border: 1px solid #eee;
width: 142px;
min-height: 20px;
list-style-type: none;
margin: 0;
padding: 5px 0 0 0;
}
.connectedSortable li {
margin: 0 5px 5px 5px;
padding: 5px;
font-size: 1.2em;
width: 120px;
}
<div>
<h1>ONLY A items</h1>
<ul id="sortable1" class="connectedSortable" data-allow-from="#sortable1">
<li class="ui-state-default">A: Item 1</li>
<li class="ui-state-default">A: Item 2</li>
</ul>
</div>
<div>
<h1>A and B items</h1>
<ul id="sortable2" class="connectedSortable" data-allow-from="#sortable1,#sortable2">
<li class="ui-state-default">B: Item 1</li>
<li class="ui-state-default">B: Item 2</li>
</ul>
</div>
<div>
<h1>A, B and C items</h1>
<ul id="sortable3" class="connectedSortable" data-allow-from="#sortable1,#sortable2,#sortable3">
<li class="ui-state-default">C: Item 1</li>
<li class="ui-state-default">C: Item 2</li>
</ul>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.css">
Upvotes: 1