Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery UI Sortable: Revert changes if update callback makes an AJAX call that fails?

I am using the sortable widget to re-order a list of items. After an item is dragged to a new location, I kick off an AJAX form post to the server to save the new order. How can I undo the sort (e.g. return the drag item to its original position in the list) if I receive an error message from the server?

Basically, I only want the re-order to "stick" if the server confirms that the changes were saved.

like image 602
Seth Petry-Johnson Avatar asked Apr 23 '10 16:04

Seth Petry-Johnson


3 Answers

Try the following:

$(this).sortable('cancel');
like image 126
thyphus Avatar answered Nov 17 '22 10:11

thyphus


I just encountered this same issue, and for the sake of a complete answer, I wanted to share my solution to this problem:

$('.list').sortable({
  items:'.list:not(.loading)',
  start: function(event,ui) { 
    var element = $(ui.item[0]);
    element.data('lastParent', element.parent());
  },
  update: function(event,ui) {
    var element = $(ui.item[0]);
    if (element.hasClass('loading')) return;
    element.addClass('loading');
    $.ajax({
      url:'/ajax',
      context:element,
      complete:function(xhr,status) {
        $(this).removeClass('loading');
        if (xhr.status != 200) {
          $($(this).data('lastParent')).append(this);
        }
      },
    });
  }
});

You'll need to modify it to suit your codebase, but this is a completely multithread safe solution that works very well for me.

like image 41
Caleb Gray Avatar answered Nov 17 '22 08:11

Caleb Gray


I'm pretty sure that sortable doesn't have any undo-last-drop function -- but it's a great idea!

In the mean time, though, I think your best bet is to write some sort of start that stores the ordering, and then on failure call a revert function. I.e. something like this:

$("list-container").sortable({
  start: function () { 
           /* stash current order of sorted elements in an array */
         },
  update: function () {
          /* ajax call; on failure, re-order based on the stashed order */
         }
});

Would love to know if others have a better answer, though.

like image 2
brahn Avatar answered Nov 17 '22 08:11

brahn