Can I change the destination of the 'revert' animation in a sortable?
I've put together a minimal example of what I'm trying to do here:
http://sab39.netreach.com/SiteData/sortable/
The idea is that the left hand side of the screen, in red, consists of
a list of items that are not currently in use, the right hand side in
green consists of a sortable list of items that are in use.
The behaviors I'm trying to achieve are:
a) The red list is not really supposed to be sortable - the items in
it are only for dragging to the right hand list - so any attempt to
move an item *within* that list should have no effect, and
b) Dragging an item to anywhere *outside* of the green list should
dump it back into the red list.
The example code I linked above actually does achieve both these goals
- as long as I don't try to turn on the 'revert' option. But the
visual feedback is pretty lousy and confusing without it, so I'd
really like to have it on.
Unfortunately, when it is turned on, it makes things worse - the
revert animation happens before my hooks that are overriding the
decision about where the item should end up, so it animates back to
its starting position and then flips to its real destination.
Hence my question: Is there any way I can pre-empt the 'revert'
animation and provide my own destination instead?
Here are the chunks of jQuery code I'm using. For the red list - this
is pretty clunky by itself but I couldn't find a way to detect which
list the item was being dropped in, other than by saving a value on
'remove' and checking it in 'stop'. But the stop doesn't happen until
after the animation is already finished so I can't pre-empt it. Trying
to use beforeStop instead made the entire thing blow up with
javascript errors. (I also tried using draggable with
connectToSortable instead, because that's really what I want, but that
had all kinds of problems including requiring 'helper: clone' which I
don't want, and nothing working until you hovered over an invisible
rectangle several inches below the green list, so I gave up on that).
$('.available-items').sortable({
tolerance: 'pointer',
connectWith: '.current-items',
remove: function(e, ui) { ui.item.include = true; },
stop: function(e, ui) { // XXX this is the problem, it
happens too late
if (!ui.item.include) $(this).sortable('cancel');
},
});
And the green list is worse, because I had to set a value on 'out' and
'over' to try to determine whether the ultimate drop location is
actually inside or outside the list. This time beforeStop worked, but
it doesn't help me, it's still not happening until the animation is
over, so the animation takes the item back to its place in the green
list - and then it teleports back to the red list.
$('.current-items').sortable({
tolerance: 'pointer',
start: function(e, ui) { ui.item.exclude = false; },
out: function(e, ui) { ui.item.exclude = true; },
over: function(e, ui) { ui.item.exclude = false; },
beforeStop: function(e, ui) { // XXX this is the
problem, it happens too late
if (ui.item.exclude) { // And even if it didn't how
could I animate to the right place?
var item = ui.item;
setTimeout(function() {
$(item).remove();
$('.available-items').append(item);
$('.available-items,current-items').sortable('refresh');
}, 1);
}
},
});
Anything I can do to get those animations going where I want them to
go? Any better solutions than I came up with for detecting whether the
eventual drop location is within the green list or outside it?
Thanks,
Stuart.