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

时间:2010-06-21 20:59:47

标签: jquery jquery-ui-draggable jquery-ui-droppable

我有一个可拖动的元素和一个可以放置的元素。一旦被拖放的项目放在dropzone上,我就会尝试执行以下jquery伪代码:

if(draggedelement == value){

$(draggedelement).hide();

}
else{

$(draggedelement).revert();

}

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

如何实现这一目标?

P.S。我知道可拖动的'revert'选项,但是只有当被拖动的项目没有进入dropzone时才会激活。

5 个答案:

答案 0 :(得分:75)

有一些内置选项,在.draggable()上,将revert option设置为'invalid',如果未成功删除,则会返回droppable,像这样:

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

然后在.droppable()中设置使用accept option对丢弃有效的内容,例如:

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

当您放手you can see a full demo here时,任何与此选择器不匹配的内容都会重置。如果您需要过滤选择器无法提供,则accept选项也会采用一个函数,如下所示:

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

答案 1 :(得分:8)

我有一个用例,我必须在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调用来更新数据库,如果服务器端逻辑说移动无效,我希望返回错误状态并恢复可拖动。

P.S。这是我的第一个答案,对不起,如果我做错了什么。关于如何提供良好答案的提示很乐意接受。

编辑:在尝试我的AJAX调用之后,我意识到droppable.drop函数有一个机会窗口可以在draggable.revert函数运行之前完成它。当我的AJAX调用返回false时,窗口已经过去了,并且为了draggable.revert做出反应,类的添加时间太晚了。

因此,我不再依赖draggable.revert函数,而是仅依赖于AJAX响应,如果为false,则使用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将draggable的原始左侧和顶部值添加为数据属性,但对我来说上面的工作正常。

答案 2 :(得分:4)

尝试将该代码添加到“drop”事件中。这是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>

脚本

$(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类或内部文本(注释掉的行)

答案 3 :(得分:1)

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

这只用于接受一组可拖动的拖车;一组正确的可放置,在一组可放置的内容中。

如果不可理解的话,对不起该语言=)

答案 4 :(得分:0)

我发现如果我只设置顶部:0和左:0,则该项目不再可拖动。为了“强制”恢复,我不得不这样做:

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