动态禁用 jQuery UI 可排序元素
Dynamically disabling jQuery UI sortable elements
我有一些 jQuery UI 可排序的父元素。每个父元素最多可以包含一个可放置的子元素,因此:
- 如果一个容器是空的,它应该能够接收来自任何其他容器的可放置元素
- 如果容器不为空:
- 它不应该能够从另一个容器接收可放置的元素
- 但当前子元素应该可以放置到任何其他空父元素
为了帮助实现这一点,父元素都有 class drop_target_cell
,空父元素有 class empty_drop_target_cell
。这些随着可放置元素的分配而更新。
为了实现这一点,我尝试在用户开始拖动可放置元素时禁用 class drop_target_cell
但不禁用 class empty_drop_target_cell
的任何元素,并且然后在拖动操作完成时使用 class drop_target_cell
重新启用所有元素。然而,这并不像我预期的那样有效;仍然可以将可放置元素拖到已有子元素的父容器中。
下面是我的最大努力,添加了背景颜色更改,这些更改(正确地)指示在拖动开始时应禁用哪些父元素:
$("#available_sections, td.drop_target_cell").sortable({
connectWith: "#available_sections, td.drop_target_cell",
start: function (event, ui) {
$("td.drop_target_cell:not(td.drop_target_cell.empty_drop_target_cell)").css('background-color', '#ff00ff');
$("td.drop_target_cell:not(td.drop_target_cell.empty_drop_target_cell)").sortable("disable");
},
stop: function (event, ui) {
$("td.drop_target_cell").css('background', 'none');
$("td.drop_target_cell").sortable("enable");
}
});
$("td.drop_target_cell").on("sortremove", function (event, ui) {
$(this).addClass('empty_drop_target_cell');
});
$("td.drop_target_cell").on("sortreceive", function (event, ui) {
$(this).removeClass('empty_drop_target_cell');
});
是否有更好的方法,或者我可以更改哪些内容以使其正常工作?
我设法使用下面的代码让它工作。所有放置目标都有 class drop_target_cell
和填充的放置目标(应该只允许删除项目)有 class populated_drop_target_cell
.
对于任何偶然发现此问题的人来说,有两个重要的教训:
要使更改生效,您必须在更改后调用 $(this).sortable("refresh")
。
可排序列表元素祖先中的任何位置 css(fixed
、relative
等)可能会干扰可排序。如果有任何事情没有按预期工作并且您找不到原因,可能就是这样。另请参阅 this question(这让我挠头好几个小时)。
$("td.drop_target_cell").sortable({
connectWith: "td.drop_target_cell",
start: function (event, ui) {
$("td.drop_target_cell.populated_drop_target_cell").sortable("option", "disabled", true);
$(this).sortable("refresh");
},
stop: function (event, ui) {
$("td.drop_target_cell").sortable("option", "disabled", false);
$(this).sortable("refresh");
}
});
我有一些 jQuery UI 可排序的父元素。每个父元素最多可以包含一个可放置的子元素,因此:
- 如果一个容器是空的,它应该能够接收来自任何其他容器的可放置元素
- 如果容器不为空:
- 它不应该能够从另一个容器接收可放置的元素
- 但当前子元素应该可以放置到任何其他空父元素
为了帮助实现这一点,父元素都有 class drop_target_cell
,空父元素有 class empty_drop_target_cell
。这些随着可放置元素的分配而更新。
为了实现这一点,我尝试在用户开始拖动可放置元素时禁用 class drop_target_cell
但不禁用 class empty_drop_target_cell
的任何元素,并且然后在拖动操作完成时使用 class drop_target_cell
重新启用所有元素。然而,这并不像我预期的那样有效;仍然可以将可放置元素拖到已有子元素的父容器中。
下面是我的最大努力,添加了背景颜色更改,这些更改(正确地)指示在拖动开始时应禁用哪些父元素:
$("#available_sections, td.drop_target_cell").sortable({
connectWith: "#available_sections, td.drop_target_cell",
start: function (event, ui) {
$("td.drop_target_cell:not(td.drop_target_cell.empty_drop_target_cell)").css('background-color', '#ff00ff');
$("td.drop_target_cell:not(td.drop_target_cell.empty_drop_target_cell)").sortable("disable");
},
stop: function (event, ui) {
$("td.drop_target_cell").css('background', 'none');
$("td.drop_target_cell").sortable("enable");
}
});
$("td.drop_target_cell").on("sortremove", function (event, ui) {
$(this).addClass('empty_drop_target_cell');
});
$("td.drop_target_cell").on("sortreceive", function (event, ui) {
$(this).removeClass('empty_drop_target_cell');
});
是否有更好的方法,或者我可以更改哪些内容以使其正常工作?
我设法使用下面的代码让它工作。所有放置目标都有 class drop_target_cell
和填充的放置目标(应该只允许删除项目)有 class populated_drop_target_cell
.
对于任何偶然发现此问题的人来说,有两个重要的教训:
要使更改生效,您必须在更改后调用
$(this).sortable("refresh")
。可排序列表元素祖先中的任何位置 css(
fixed
、relative
等)可能会干扰可排序。如果有任何事情没有按预期工作并且您找不到原因,可能就是这样。另请参阅 this question(这让我挠头好几个小时)。$("td.drop_target_cell").sortable({ connectWith: "td.drop_target_cell", start: function (event, ui) { $("td.drop_target_cell.populated_drop_target_cell").sortable("option", "disabled", true); $(this).sortable("refresh"); }, stop: function (event, ui) { $("td.drop_target_cell").sortable("option", "disabled", false); $(this).sortable("refresh"); } });