Jquery 可排序:连接列表,具有基于原始列表来源的限制
Jquery Sortable: Connect lists, with restrictions based on original list source
我有两个可排序列表,A 和 B,使用 Jquery 的 Sortable 创建。
这是我需要的:
从列表 A 开始的项目应该可以在列表 A 和列表 B 之间排序(也可以来回排序)。但是,从列表 B 开始的项目永远不应移到列表 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();
});
以下示例分为两个主要部分:识别每个可拖动元素的原点和检查是否允许放置。
识别来源
首先,我们需要确定要拖动的每个元素的原点。在这种情况下,来源是第一个包含该元素的列表的 id
属性。该值将存储在名为 data-origin
.
的属性中
$('.connectedSortable').find('li').attr('data-origin', function () {
var $parent = $(this).parents('ul');
return '#' + $parent.attr('id');
});
检查是否允许放置
您可以使用 receive
事件来实现将验证是否允许将元素放入列表中的算法。
要取消掉落,只需调用方法.cancel()
。
为了使示例更通用,我在每个列表中创建了一个附加属性 data-allow-from
,指示它可以从哪些其他列表接收元素。
然后我们只创建一个简单的回调函数,它将在每个列表的 receive
事件上调用,获取被删除元素的来源并检查它是否在允许的列表中。
例子
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">
我有两个可排序列表,A 和 B,使用 Jquery 的 Sortable 创建。
这是我需要的:
从列表 A 开始的项目应该可以在列表 A 和列表 B 之间排序(也可以来回排序)。但是,从列表 B 开始的项目永远不应移到列表 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();
});
以下示例分为两个主要部分:识别每个可拖动元素的原点和检查是否允许放置。
识别来源
首先,我们需要确定要拖动的每个元素的原点。在这种情况下,来源是第一个包含该元素的列表的 id
属性。该值将存储在名为 data-origin
.
$('.connectedSortable').find('li').attr('data-origin', function () {
var $parent = $(this).parents('ul');
return '#' + $parent.attr('id');
});
检查是否允许放置
您可以使用 receive
事件来实现将验证是否允许将元素放入列表中的算法。
要取消掉落,只需调用方法.cancel()
。
为了使示例更通用,我在每个列表中创建了一个附加属性 data-allow-from
,指示它可以从哪些其他列表接收元素。
然后我们只创建一个简单的回调函数,它将在每个列表的 receive
事件上调用,获取被删除元素的来源并检查它是否在允许的列表中。
例子
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">