如何根据条件恢复 jquery UI 可拖动的位置

发布于 2024-09-06 15:52:02 字数 327 浏览 5 评论 0原文

我有一个可拖动的元素和一个可放置的元素。一旦拖动的项目被放到拖放区上,我将尝试执行以下 jquery psuedo 代码:

if(draggedelement == value){

$(draggedelement).hide();

}
else{

$(draggedelement).revert();

}

其中 revert() 函数将拖动的项目移回其原始位置。

如何实现这一目标?

PS 我知道可拖动的“恢复”选项,但是只有当拖动的项目没有到达放置区时才会激活。

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:

if(draggedelement == value){

$(draggedelement).hide();

}
else{

$(draggedelement).revert();

}

where the revert() function moves the dragged item back to its original postion.

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

夜声 2024-09-13 15:52:02

在您的 .draggable(),将 revert 选项 设置为 ' invalid',如果它没有成功地放置到可放置的对象上,它会返回,如下所示:

$("#draggable").draggable({ revert: 'invalid' });

然后在您的 .droppable() 使用 接受选项,例如:

$("#droppable").droppable({ accept: '#draggable' });​

当您放开时,任何不匹配此选择器的内容都会被重置,您可以在此处查看完整的演示。如果您需要过滤选择器无法提供的功能,则接受选项还需要一个函数,如下所示:

$("#droppable").droppable({ 
  accept: function(dropElem) {
    //dropElem was the dropped element, return true or false to accept/refuse it
  }
});​

There are some built-in options for this, on your .draggable(), set the revert option to 'invalid', and it'll go back if it wasn't successfully dropped onto a droppable, like this:

$("#draggable").draggable({ revert: 'invalid' });

Then in your .droppable() set what's valid for a drop using the accept option, for example:

$("#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:

$("#droppable").droppable({ 
  accept: function(dropElem) {
    //dropElem was the dropped element, return true or false to accept/refuse it
  }
});​
薄凉少年不暖心 2024-09-13 15:52:02

我有一个用例,我必须在 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');
    }
  }
});

我的用例是一个表格,其中每个单元格都是代表 5 分钟时间段的可放置单元格。我的可拖动对象是从一个单元格开始的预订,但连续运行多个单元格来表示预订时间。

我不希望任何可拖动项重叠,因为这代表重复预订。因此,在放置之后,我会找到该行中的所有可拖动对象(不包括我刚刚移动的可拖动对象),并检查是否有任何重叠。如果存在重叠,我的条件逻辑将返回 true,并恢复可拖动。

下一阶段是触发 ajax 调用来更新数据库,如果服务器端逻辑表明移动无效,我希望返回错误状态并恢复可拖动。

PS这是我的第一次回答,如果我做错了什么,抱歉。关于如何提供良好答案的提示很高兴被接受。

编辑:在尝试我的 AJAX 调用之后,我意识到 droppable.drop 函数在运行draggable.revert 函数之前有一个机会来做它的事情。当我的 AJAX 调用返回 false 时,窗口已经过去,添加类已经太晚了,无法让 Draggable.revert 做出反应。

因此,我不再依赖draggable.revert函数,而是仅作用于AJAX响应,如果为假,则使用animate()将draggable返回到其原始位置,如下所示:

$( '.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 );
      }
    }
  }
});

您可能需要将draggable.start/drag添加可拖动的原始左侧值和顶部值作为数据属性,但对我来说,上面的方法工作得很好。

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:

$('.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.

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.

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.

P.S. this is my first answer, sorry if I've done anything wrong. Tips on how to provide good answers gladly accepted.

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.

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-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.

太阳公公是暖光 2024-09-13 15:52:02

尝试将该代码添加到“drop”事件中。这是一个演示

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>

脚本

$(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);
   }
  }
 });

});

正如您在脚本中看到的,您可以查找 . Correct 类或其中的文本(注释掉的行)

Try adding that code into the "drop" event. Here is a demo.

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)

怎樣才叫好 2024-09-13 15:52:02
$("#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;
    }
}
});​

这用于仅接受一组可拖动对象中的一个可拖动对象;一组 droppable 中的一个正确的 droppable。

PS 如果语言无法理解,请见谅 =)

$("#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.

P.S sorry for the language if it is not understandable =)

摘星┃星的人 2024-09-13 15:52:02

我发现如果我简单地设置top:0和left:0,该项目就不再可拖动。为了“强制”恢复,我必须这样做:

$draggedObj.css({ top: 0, left: 0 })
$draggedObj.draggable( "destroy" )
$draggedObj.draggable({...whatever my draggable options are...});

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:

$draggedObj.css({ top: 0, left: 0 })
$draggedObj.draggable( "destroy" )
$draggedObj.draggable({...whatever my draggable options are...});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文