限制与 draggables 和 droppable 相关联的 sortable 中的元素数量
limit number of elements in a sortable connected with draggables and a droppable
我有一个可排序的、连接的可拖动对象和一个可放置对象。
它基本上是一个桶和一个可排序的项目列表。
我想限制您可以从存储桶拖到列表中的项目数。
我的问题是,如果列表中的项目数太多,我就无法恢复可拖动。我还从列表中删除了该项目,因此它也不会卡在那里。
但这是我的问题。 sortable 的更新事件最后触发。因此,当更新事件触发时,元素已被删除,因此项目数量少于允许的数量。我不想要这个,因为我在更新事件中更新了我的数据库。
我知道这个问题之前已经回答过,但请先阅读整个问题。
这里是 html:
<fieldset id="container">
<div style="float: left; width: 49%;">
<fieldset class="choosen" style="float: left; width: 100%;">
<legend>choosen</legend>
<div style="overflow-y: auto; height: 40em;" class="box">
<ul style="min-height: 40em;" class="imglist grey sortable">
<li data-id="1" class="acceptable">Element1</li>
<li data-id="2" class="acceptable">Element2</li>
<li data-id="3" class="acceptable">Element3</li>
</ul>
</div>
</fieldset>
</div>
<div style="float: left; margin-left: 2%; width: 49%;">
<fieldset class="bucket" style="float: left; width: 100%;">
<legend>bucket</legend>
<div style="overflow-y: auto; height: 40em;" class="box droppable">
<ul style="min-height: 40em;" class="imglist grey">
<li data-id="5" class="draggable"><a>Element5</a>
</li>
<li data-id="6" class="draggable"><a>Element6</a>
</li>
<li data-id="7" class="draggable"><a>Element7</a>
</li>
<li data-id="8" class="draggable"><a>Element8</a>
</li>
</ul>
</div>
</fieldset>
</div>
这里是 jquery 代码:
var helperClone = function (event, object) {
if (undefined == object) {
var helper = $(this).clone(),
height = $(this).height(),
width = $(this).width();
} else {
var helper = object.clone(),
height = object.height(),
width = object.width();
}
helper.css({'width': width, 'height': height});
return helper;
},
sortable = $(".sortable"),
draggable = $(".draggable"),
revertCheck = function () {
console.log("revertCheck", sortable.find("li").length > 4, sortable.find("li").length);
if (sortable.find("li").length > 4) {
return true;
}
return false;
};
draggable.draggable({
connectToSortable: sortable,
helper: helperClone,
revert: revertCheck
});
sortable.sortable({
placeholder: "ui-state-highlight",
helper: helperClone,
receive: function (event, ui) {
console.log("receive", $(this).find("li").length < 4, $(this).find("li").length);
if ($(this).find("li").length < 4) {
ui.item.remove();
$(this).data().uiSortable.currentItem.addClass('acceptable').css({
'width': '100%',
'height': 'unset'
});
} else {
ui.helper.remove();
}
},
update: function (event, ui) {
console.log("update", $(this).find("li").length < 4, $(this).find("li").length);
if ($(this).find("li").length < 4) {
//do stuff
console.log("update fired");
} else {
console.log("update didn't fire");
ui.item.effect('highlight', {
color: 'red'
});
}
}
});
$(".droppable").droppable({
accept: 'li.acceptable',
over: function (event, ui) {
$(this).effect('highlight');
},
drop: function (event, ui) {
var target = $(this).find('ul');
var clone = ui.draggable.clone().css({
'display': 'list-item',
'position': 'unset'
});
ui.draggable.remove();
clone.appendTo(target).show().removeClass('acceptable').draggable({
connectToSortable: sortable,
containment: "#container",
helper: helperClone,
revert: revertCheck
});
}
});
$("ul, li").disableSelection();
这是一个工作示例:http://jsfiddle.net/adq6exkp/
其他答案建议在可排序的接收事件中调用sortable.sortable("cancel");
。所以在上面的代码中,您可以将其添加到接收事件函数的 else 部分:
$(ui.sender).sortable('cancel');
问题是这引发了以下错误:
Error: cannot call methods on sortable prior to initialization; attempted to call method 'cancel'
http://code.jquery.com/jquery-1.10.1.js
Line 516
这里是这个错误的工作示例:http://jsfiddle.net/adq6exkp/1/
据我了解,您不希望在发生还原时触发更新。
您可以使用布尔值完成此操作。
sortable.sortable({
placeholder: "ui-state-highlight",
helper: helperClone,
receive: function (event, ui) {
console.log("receive", $(this).find("li").length < 4, $(this).find("li").length);
if ($(this).find("li").length < 4) {
ui.item.remove();
$(this).data().uiSortable.currentItem.addClass('acceptable').css({
'width': '100%',
'height': 'unset'
});
} else {
this.reverted = true;
ui.helper.remove();
}
},
update: function (event, ui) {
console.log("update", $(this).find("li").length < 4, $(this).find("li").length);
if (!this.reverted) {
//do stuff
console.log("update fired");
} else {
this.reverted = false;
console.log("update didn't fire");
ui.item.effect('highlight', {
color: 'red'
});
}
}
});
您可以在 update
事件中处理 helper
删除。这样,列表中的元素数量在 receive
和 update
上都是一致的。但是由于你没有权限访问update
事件中的helper
,所以你需要先存储它。这可以在 receive
事件上完成。这样:
receive: function (event, ui) {
//store current helper
cur_helper = ui.helper;
console.log("receive", $(this).find("li").length < 4, $(this).find("li").length);
if ($(this).find("li").length < 4) {
ui.item.remove();
$(this).data().uiSortable.currentItem.addClass('acceptable').css({
'width': '100%',
'height': 'unset'
});
}
},
update: function (event, ui) {
console.log("update", $(this).find("li").length < 4, $(this).find("li").length);
if ($(this).find("li").length < 4) {
//do stuff
console.log("update fired");
} else {
//remove the helper if the list exceeds 3
cur_helper.remove();
console.log("update didn't fire");
ui.item.effect('highlight', {
color: 'red'
});
}
}
fiddle: http://jsfiddle.net/p0nft4mj/
我有一个可排序的、连接的可拖动对象和一个可放置对象。 它基本上是一个桶和一个可排序的项目列表。 我想限制您可以从存储桶拖到列表中的项目数。
我的问题是,如果列表中的项目数太多,我就无法恢复可拖动。我还从列表中删除了该项目,因此它也不会卡在那里。 但这是我的问题。 sortable 的更新事件最后触发。因此,当更新事件触发时,元素已被删除,因此项目数量少于允许的数量。我不想要这个,因为我在更新事件中更新了我的数据库。
我知道这个问题之前已经回答过,但请先阅读整个问题。
这里是 html:
<fieldset id="container">
<div style="float: left; width: 49%;">
<fieldset class="choosen" style="float: left; width: 100%;">
<legend>choosen</legend>
<div style="overflow-y: auto; height: 40em;" class="box">
<ul style="min-height: 40em;" class="imglist grey sortable">
<li data-id="1" class="acceptable">Element1</li>
<li data-id="2" class="acceptable">Element2</li>
<li data-id="3" class="acceptable">Element3</li>
</ul>
</div>
</fieldset>
</div>
<div style="float: left; margin-left: 2%; width: 49%;">
<fieldset class="bucket" style="float: left; width: 100%;">
<legend>bucket</legend>
<div style="overflow-y: auto; height: 40em;" class="box droppable">
<ul style="min-height: 40em;" class="imglist grey">
<li data-id="5" class="draggable"><a>Element5</a>
</li>
<li data-id="6" class="draggable"><a>Element6</a>
</li>
<li data-id="7" class="draggable"><a>Element7</a>
</li>
<li data-id="8" class="draggable"><a>Element8</a>
</li>
</ul>
</div>
</fieldset>
</div>
这里是 jquery 代码:
var helperClone = function (event, object) {
if (undefined == object) {
var helper = $(this).clone(),
height = $(this).height(),
width = $(this).width();
} else {
var helper = object.clone(),
height = object.height(),
width = object.width();
}
helper.css({'width': width, 'height': height});
return helper;
},
sortable = $(".sortable"),
draggable = $(".draggable"),
revertCheck = function () {
console.log("revertCheck", sortable.find("li").length > 4, sortable.find("li").length);
if (sortable.find("li").length > 4) {
return true;
}
return false;
};
draggable.draggable({
connectToSortable: sortable,
helper: helperClone,
revert: revertCheck
});
sortable.sortable({
placeholder: "ui-state-highlight",
helper: helperClone,
receive: function (event, ui) {
console.log("receive", $(this).find("li").length < 4, $(this).find("li").length);
if ($(this).find("li").length < 4) {
ui.item.remove();
$(this).data().uiSortable.currentItem.addClass('acceptable').css({
'width': '100%',
'height': 'unset'
});
} else {
ui.helper.remove();
}
},
update: function (event, ui) {
console.log("update", $(this).find("li").length < 4, $(this).find("li").length);
if ($(this).find("li").length < 4) {
//do stuff
console.log("update fired");
} else {
console.log("update didn't fire");
ui.item.effect('highlight', {
color: 'red'
});
}
}
});
$(".droppable").droppable({
accept: 'li.acceptable',
over: function (event, ui) {
$(this).effect('highlight');
},
drop: function (event, ui) {
var target = $(this).find('ul');
var clone = ui.draggable.clone().css({
'display': 'list-item',
'position': 'unset'
});
ui.draggable.remove();
clone.appendTo(target).show().removeClass('acceptable').draggable({
connectToSortable: sortable,
containment: "#container",
helper: helperClone,
revert: revertCheck
});
}
});
$("ul, li").disableSelection();
这是一个工作示例:http://jsfiddle.net/adq6exkp/
其他答案建议在可排序的接收事件中调用sortable.sortable("cancel");
。所以在上面的代码中,您可以将其添加到接收事件函数的 else 部分:
$(ui.sender).sortable('cancel');
问题是这引发了以下错误:
Error: cannot call methods on sortable prior to initialization; attempted to call method 'cancel' http://code.jquery.com/jquery-1.10.1.js Line 516
这里是这个错误的工作示例:http://jsfiddle.net/adq6exkp/1/
据我了解,您不希望在发生还原时触发更新。
您可以使用布尔值完成此操作。
sortable.sortable({
placeholder: "ui-state-highlight",
helper: helperClone,
receive: function (event, ui) {
console.log("receive", $(this).find("li").length < 4, $(this).find("li").length);
if ($(this).find("li").length < 4) {
ui.item.remove();
$(this).data().uiSortable.currentItem.addClass('acceptable').css({
'width': '100%',
'height': 'unset'
});
} else {
this.reverted = true;
ui.helper.remove();
}
},
update: function (event, ui) {
console.log("update", $(this).find("li").length < 4, $(this).find("li").length);
if (!this.reverted) {
//do stuff
console.log("update fired");
} else {
this.reverted = false;
console.log("update didn't fire");
ui.item.effect('highlight', {
color: 'red'
});
}
}
});
您可以在 update
事件中处理 helper
删除。这样,列表中的元素数量在 receive
和 update
上都是一致的。但是由于你没有权限访问update
事件中的helper
,所以你需要先存储它。这可以在 receive
事件上完成。这样:
receive: function (event, ui) {
//store current helper
cur_helper = ui.helper;
console.log("receive", $(this).find("li").length < 4, $(this).find("li").length);
if ($(this).find("li").length < 4) {
ui.item.remove();
$(this).data().uiSortable.currentItem.addClass('acceptable').css({
'width': '100%',
'height': 'unset'
});
}
},
update: function (event, ui) {
console.log("update", $(this).find("li").length < 4, $(this).find("li").length);
if ($(this).find("li").length < 4) {
//do stuff
console.log("update fired");
} else {
//remove the helper if the list exceeds 3
cur_helper.remove();
console.log("update didn't fire");
ui.item.effect('highlight', {
color: 'red'
});
}
}
fiddle: http://jsfiddle.net/p0nft4mj/