如何根据条件恢复可拖动的 jquery UI 的位置
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3088485/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to revert position of a jquery UI draggable based on condition
提问by Mazatec
I have an element which is draggable and an element which is droppable. Once the dragged item is dropped on the dropzone I am trying to execute the following jquery psuedo code:
我有一个可拖动的元素和一个可放置的元素。将拖动的项目放在 dropzone 上后,我将尝试执行以下 jquery 伪代码:
if(draggedelement == value){
$(draggedelement).hide();
}
else{
$(draggedelement).revert();
}
where the revert()
function moves the dragged item back to its original postion.
该revert()
函数将拖动的项目移回其原始位置。
How would one accomplish this?
怎样才能做到这一点?
P.S. I am aware of the draggable 'revert' option, however this only activates if the dragged item does not make it to the dropzone.
PS我知道可拖动的“恢复”选项,但是只有在拖动的项目没有进入放置区时才会激活。
回答by Nick Craver
There are some built-in options for this, on your .draggable()
, set the revert
optionto 'invalid'
, and it'll go back if it wasn't successfully dropped onto a droppable, like this:
对此有一些内置选项,在您的 上.draggable()
,将revert
选项设置为'invalid'
,如果它没有成功地放到一个 droppable 上,它将返回,如下所示:
$("#draggable").draggable({ revert: 'invalid' });
Then in your .droppable()
set what's valid for a drop using the accept
option, for example:
然后在您的.droppable()
设置中使用accept
option对drop 有效的内容,例如:
$("#droppable").droppable({ accept: '#draggable' });?
Anything not matching this selector gets reset when you let go, you can see a full demo here. The accept option also takes a function if you need filtering a selector can't provide, like this:
当你放手时,任何不匹配这个选择器的东西都会被重置,你可以在这里看到完整的演示。如果您需要过滤选择器无法提供的功能,accept 选项也有一个功能,如下所示:
$("#droppable").droppable({
accept: function(dropElem) {
//dropElem was the dropped element, return true or false to accept/refuse it
}
});?
回答by PaulPrecept
I had a use case where I had to run some logic in the droppable's drop method to determine if the draggable should revert. I used the following to achieve this:
我有一个用例,我必须在 droppable 的 drop 方法中运行一些逻辑来确定draggable 是否应该恢复。我使用以下方法来实现这一点:
$('.draggable-elements').draggable({
revert: function() {
if ($(this).hasClass('drag-revert')) {
$(this).removeClass('drag-revert');
return true;
}
}
});
$('.droppable-elements').droppable({
drop: function(event, ui) {
if ( % conditional logic check here % ) {
return $(ui.draggable).addClass('drag-revert');
}
}
});
My use case is a table where each cell is a droppable representing a 5 minute period. My draggables are bookings which start in one cell, but run over many cells in a row to represent the booking time.
我的用例是一个表格,其中每个单元格都是一个表示 5 分钟时间段的 droppable。我的可拖动对象是从一个单元格开始的预订,但连续运行多个单元格以表示预订时间。
I did not want any draggables to overlap, as that would represent a double booking. So, after the drop I find all draggables in the row, excluding the one I just moved, and check for any overlaps. If there is an overlap, my conditional logic returns true and I revert the draggable.
我不希望任何可拖动对象重叠,因为这将代表双重预订。所以,在放下之后,我找到了行中的所有可拖动对象,不包括我刚刚移动的那个,并检查是否有任何重叠。如果有重叠,我的条件逻辑返回 true 并恢复可拖动。
Next stage is to fire an ajax call to update the database, if server-side logic says the move is invalid I hope to return an error status and revert the draggable.
下一阶段是触发 ajax 调用来更新数据库,如果服务器端逻辑说移动无效,我希望返回错误状态并恢复可拖动。
P.S. this is my first answer, sorry if I've done anything wrong. Tips on how to provide good answers gladly accepted.
PS这是我的第一个答案,对不起,如果我做错了什么。很高兴接受有关如何提供良好答案的提示。
Edit: After trying my AJAX call, I realised there is a window of opportunity for the droppable.drop function to do it's thing before the draggable.revert function runs. By the time my AJAX call returned false, the window had passed and the class was being added too late for draggable.revert to react.
编辑:在尝试我的 AJAX 调用后,我意识到 droppable.drop 函数有一个机会在 draggable.revert 函数运行之前完成它。当我的 AJAX 调用返回 false 时,窗口已经过去,并且该类被添加为时已晚,draggable.revert 无法做出反应。
As such, I'm no longer relying on the draggable.revert function, instead acting solely on the AJAX response and if false, using animate() to return the draggable to it's original position, as follows:
因此,我不再依赖 draggable.revert 函数,而是仅根据 AJAX 响应执行操作,如果为 false,则使用 animate() 将可拖动对象返回到其原始位置,如下所示:
$( '.draggable-elements' ).draggable();
$( '.droppable-elements' ).droppable({
drop: function( event, ui ) {
var postData = {
id: 1,
...
};
$.post( '/ajax/url', postData, function( response ) {
var response = $.parseJSON( response );
if ( response.status != 1 ) {
return ui.draggable.animate( {left: 0, top: 0}, 500 );
}
}
}
});
You may need to have draggable.start/drag add the original left and top values of the draggable as data attributes, but for me the above worked fine.
您可能需要将 draggable.start/drag 添加可拖动的原始左值和上值作为数据属性,但对我来说,上述工作正常。
回答by Mottie
Try adding that code into the "drop" event. Here is a demo.
尝试将该代码添加到“drop”事件中。这是一个演示。
HTML
HTML
<div class="draggable ui-widget-content correct"><p>1</p></div>
<div class="draggable ui-widget-content"><p>2</p></div>
<div class="draggable ui-widget-content"><p>3</p></div>
<div class="draggable ui-widget-content"><p>4</p></div>
<br style="clear: both">
<div id="droppable" class="ui-widget-header">
<p>Drop me here</p>
</div>
Script
脚本
$(function() {
$(".draggable").draggable({ revert: true });
$("#droppable").droppable({
activeClass: 'ui-state-hover',
hoverClass: 'ui-state-active',
// uncomment the line below to only accept the .correct class..
// Note: the "drop" function will not be called if not ".correct"
// accept : '.correct',
drop: function(event, ui) {
// alternative method:
// if (ui.draggable.find('p').text() == "1") {
if (ui.draggable.is('.correct')) {
$(this).addClass('ui-state-highlight').find('p').html('You got it!');
// cloning and appending prevents the revert animation from still occurring
ui.draggable.clone(true).css('position', 'inherit').appendTo($(this));
ui.draggable.remove();
} else {
$('#droppable > p').html('Not that one!')
setTimeout(function(){ $('#droppable > p').html('Drop here'); }, 1000);
}
}
});
});
As you can see in the script, you can either look for the .correct
class or the text inside (commented out line)
正如您在脚本中看到的,您可以在里面查找.correct
类或文本(注释掉的行)
回答by Roshan Poudyal
$("#droppable").droppable({
accept: function(dropElem) {
//dropElem was the dropped element, return true or false to accept/refuse it
if($(this).data('stoneclass') == dropElem.attr("id")){
return true;
}
}
});?
This was used to accept only one draggable, from a group of draggables ; to one correct droppable, in a group of droppables.
这用于仅接受来自一组 draggables 的一个 draggable ;到一个正确的 droppable,在一组 droppable 中。
P.S sorry for the language if it is not understandable =)
PS,如果语言无法理解,请见谅 =)
回答by Peter Hollingsworth
I found that if I simply set top:0 and left:0, the item is no longer draggable. In order to "force" a revert I had to do this:
我发现如果我简单地设置 top:0 和 left:0,则该项目不再可拖动。为了“强制”恢复,我必须这样做:
$draggedObj.css({ top: 0, left: 0 })
$draggedObj.draggable( "destroy" )
$draggedObj.draggable({...whatever my draggable options are...});