JQuery drag and drop callback called after sorting from sortable
I have a list of drag and drop objects associated with a sort list. The drag and drop function works great, as does the sort. The thing is, before sorting the list, I need to create a record in the DB (using rails). So I use $ .post, which works great, but I need to change the id of the inserted item. I do this by changing the id of the inserted item using the $ .post callback. Works fine, but it happens AFTER sorting. And if you're wondering why I didn't use the draggable stop callback because it does the same thing. Here's the shorthand code (remove unnecessary db stuff):
$("#operations_container").sortable({items:'.process_small', axis:'y', update: function(ev,ui) {
if (ui.item.attr('id').match("workcenter"))
{
$.post('/operations', 'fancyrailspoststuffignore', function(data) {
$("#operations_container > #workcenter_" + workcenterid).attr("id", "operation_" + data.operation.id);
}, "json");
}
$.post('/jobs/sort/<%= @job.id %>', 'morefancyschamncyrailsjunk);
}});
The sorted container is simple:
<div id="operations_container" class="in_grid">
</div>
So, it seems to me that all calls are called after sorting. It's true? How do you get around this if you need to update the DOM before sorting?
UPDATE: In case they are missing in the comments, here are sample images and examples to illustrate the issue.
Image: http://dl.getdropbox.com/u/1826667/sortable.png Sample files: http://dl.getdropbox.com/u/1826667/jquery_callback_order.zip
So it seems that callbacks always end at the end of any other events no matter where they are called (@ .post callback before the update being sorted is still called last, etc.). I don't think this is a bug in JQuery (although I find it strange); I am trying to make multiple posts (which are required as they depend on each other, create a record and then sort) in a single move, which may not be the way to do it. I will try to work around this in the backend (something almost works for me) so I will consider it private. Thanks to everyone who helped with the problem. SO rules.
MEGAIMPORTANTUPDATE: it works! Sean got this (see answer) and I'm still a little dizzy. It's been a few days on this one. Thanks again to everyone, and especially Sean. You rock.
source to share
Aha! Got it. This picture was exactly what I needed. Here's what to do:
$("#operations_container").sortable({items:'.process_small', axis:'y', update: function(ev,ui) {
var sortDbTable = function(){
$.post('/jobs/sort/<%= @job.id %>', 'morefancyschamncyrailsjunk);
}
if (ui.item.attr('id').match("workcenter"))
{
$.post('/operations', 'fancyrailspoststuffignore', function(data) {
$("#operations_container > #workcenter_" + workcenterid).attr("id", "operation_" + data.operation.id); //is there any reason you're not using the ui.item.attr("id",...) here?
sortDbTable(); //this will make sure id is changed before DB sort
}, "json");
} else { //else not absolutely needed, but will make sure it not unnecessarily sorted again
sortDbTable();
}
}});
source to share