In jQuery, how to revert a draggable on ajax call

2020-05-24 02:54发布

问题:

I want the draggable to be reverted to its original position if the ajax call on drop returns a failure. Here is the code what I am imagining it to be.. It is OK if the draggable rests in the droppable while the ajax call is in process...

<script type="text/javascript">
jQuery(document).ready($){
    $("#dragMe").draggable();
    $("#dropHere").droppable({
        drop: function(){
            // make ajax call here. check if it returns success.
            // make draggable to return to its old position on failure.
        }
    });
}
</script>
<div id="dragMe">DragMe</div>
<div id="dropHere">DropHere</div>

回答1:

Thanks for your replay @Fran Verona.

I solved it this way:

<script type="text/javascript">
jQuery(document).ready($){
    $("#dragMe").draggable({
        start: function(){
        $(this).data("origPosition",$(this).position());
        }
    });
    $("#dropHere").droppable({
        drop: function(){
            //make ajax call or whatever validation here. check if it returns success.
            //returns result = true/false for success/failure;

            if(!result){ //failed
                ui.draggable.animate(ui.draggable.data().origPosition,"slow");
                return;
            }
            //handling for success..
        }
    });
}
</script>
<div id="dragMe">DragMe</div>
<div id="dropHere">DropHere</div>

Wanted to avoid any new global variables, also the number of variables was unpredictable as many drag-drops can happen while the first is in progress, i.e. before the 1st call returns..! BTW, for anyone looking for the same answer, .data() does not work on all elements, I am not sure about jQuery.data(), though.. Let me know if anyone finds anything wrong in this! :)



回答2:

I was looking on the net for the same draggable question this morning.

The NikhilWanpal's solution works but sometimes the revert position is incorrect in my case perhaps because my draggable elements are contained in a scrollable container.

I found this article which explain how to implement a very useful undocumented function : jQuery UI Draggable Revert Callback.

Check your answer in this callback (if it is possible for you) and return "TRUE" to cancel or "FASLE" to confirm the new position.

$(".peg").draggable(
{
  revert: function(socketObj)
  {
     //if false then no socket object drop occurred.
     if(socketObj === false)
     {
        //revert the peg by returning true
        return true;
     }
     else
     {
        //socket object was returned,
        //we can perform additional checks here if we like
        //alert(socketObj.attr('id')); would work fine

        //return false so that the peg does not revert
        return false;
     }
  },
  snap: '.socketInner',
  snapMode: 'inner',
  snapTolerance: 35,
  distance: 8,
  stack: { group: 'pegs', min:50 },
  stop: function()
  {
     draggedOutOfSocket = false;
     alert('stop');
  }
} );

Have a nice day



回答3:

If you're not otherwise messing around with left or top positioning on the draggable elements, it's as simple as resetting these css properties once the ajax call errors out:

drop_elems.droppable({
  drop: function(event, ui) {
    $.ajax(url, {
      error: function(x, t, e) {
        ui.draggable.css({top: 0, left: 0});
      },
    });
  }
});


回答4:

Try to save the original position before starting to drag and restore it if drops fail. You can save the original position like this:

var dragposition = '';

$('#divdrag').draggable({
   // options...
   start: function(event,ui){
      dragposition = ui.position;
   }
});

$("#dropHere").droppable({
   drop: function(){
       $.ajax({
           url: 'myurl.php',
           data: 'html',
           async: true,
           error: function(){
               $('#divdrag').css({
                  'left': dragposition.left,
                  'top': dragposition.top
               });
           }
       });
   }
});


回答5:

Reset it this way. it allows you to animate the property top and left to the original position

$("#dropHere").droppable({
        drop: function(){

            if(!result){ //failed
               ui.draggable.animate(ui.draggable.data("ui-draggable").originalPosition,"slow");

            }
            else{ //instructions for success}

        }
    });