TLDR
I want to be able to animate my jQuery-UI sortable after the helper has been dropped by showing the original item moving to it's new position with the others shifting around. This is complicated by certain sortables needing to be fixed in position.
The Project:
The project involves dynamically generated jQuery-UI portlets within a tabbed interface. The tabs and portlet contents themselves are generated through async AJAX requests to established web services. Each tab has an undetermined number of portlets within it, and uses custom scrollbars for content display. I have implemented the fixing of certain portlets using classes and a solution found elsewhere on stack overflow (slightly modified). A very basic implementation of current functionality can be seen here: http://jsfiddle.net/99yVq/.
The Problem
Prior to implementing portlet fixing I was animating while sorting by showing and hiding the placeholder element:
$( ".content" ).sortable({
start: function(e, ui){
$(ui.placeholder).hide(300);
},
change: function (e,ui){
$(ui.placeholder).hide().show(300);
}
});
Viewable in action here: http://jsfiddle.net/BWNE2/. This works fairly well but I feel the animation is choppy and it will obviously require some poking to get it to work with the portlet fixing solution above (as it relies on helper creation to determine fixed positions). It is not the solution I'm looking for.
Update
Did the poking to combine the two (none was really needed with a caveat) and the combined functionality is available here: http://jsfiddle.net/BWNE2/1/. The animations work but as you can see the .fixed portlet animates along with the others and then reverts back to it's original position.
End of Update
The Question
My ideal scenario would be for the user to drag the portlet helper (which I believe is a clone of the original item used during dragging) from its original position to it's new one. At the point of dropping the portlets would then animate from there old positions to the new. The current movement during sorting should be maintained to give the end user feedback, but the final animations should take place after the drop of the helper.
Does anyone have any ideas or examples of how to achieve this?
If my question format is inadequate or you require more information on anything please let me know.
Thanks in advance.
Edit
You can see here: http://jsfiddle.net/BWNE2/2/ that the animation effect is even more inadequate when the fixed portlet it in position 3 (top right of the top section). It is often not in the correct position while sorting, though it does revert to the correct place on sort end.
Following the solution found in other question, which is basically when dragging you clone the itens and animate them to the new positions, I merged that into your code.
What this code didn't had was the animation after the release, which i made by saving the position on the mouseup
event, and animating the dragged element to the final position.
Final fiddle: http://jsfiddle.net/hTgad/
Code:
var lastPosition;
$( "#content" ).sortable({
delay: 100,
distance: 10,
handle: '.portlet-header',
items: '.portlet:not(.fixed)',
start: function(e, ui)
{
//store the fixed itens position
$('.fixed', this).each(function(){
var $this = $(this);
$this.data('pos', $this.index());
});
// Identify the item being dragged
ui.helper.addClass("being-dragged");
var clonedItems = $("#cloned_items");
// Create a clone for every item, except the fixed ones and the one being dragged
$("#content .portlet:not(.being-dragged, .ui-sortable-placeholder, .fixed)").each(function(){
// clone the original items to make their
// absolute-positioned counterparts...
var original = $(this);
var clone = original.clone();
// 'store' the clone for later use...
original.data("clone", clone);
original.css("visibility", "hidden"); // Hide the original
// set the initial position of the clone
var position = original.position();
clone.css("left", position.left)
.css("top", position.top);
// append the clone...
clonedItems.append(clone);
});
},
change: function(e,ui)
{
//change the position of the fixed elements to the original one
$sortable = $(this);
$statics = $('.fixed', this).detach();
$helper = $('<div class="portlet" style="background-color:#000"></div>').prependTo(this);
$statics.each(function(){
var $this = $(this);
var target = $this.data('pos');
$this.insertAfter($('.portlet', $sortable).eq(target));
});
$helper.remove();
// animate all clones to the new position
$("#content .portlet:not(.being-dragged, .ui-sortable-placeholder, .fixed)").each(function(){
var item = $(this);
var clone = item.data("clone");
// stop current clone animations...
clone.stop(true, false);
var position = item.position(); // New position
clone.animate({left: position.left, top:position.top}, 500);
});
},
stop: function(e, ui){
var el = $("#content .being-dragged");
// Save the new position
var newPosition = el.position();
// Insert a placeholder for the final animation
$('<div class="portlet ui-sortable-placeholder"></div>').insertBefore(el);
el.css("left", lastPosition.left)
.css("top", lastPosition.top)
.css("position", "absolute")
.animate({left: newPosition.left, top: newPosition.top}, 300, "swing", function() {
// After the animation remove the placeholder and reset the element position
$("#content .ui-sortable-placeholder").remove();
$(this).css("left", "").css("top", "").css("position", "");
})
.removeClass("being-dragged");
// Erase the temporary itens
$("#cloned_items").empty();
// make sure all our original items are visible again...
$("#content .portlet").css("visibility", "visible");
}
});
// Save the position of the element being dragged for the final animation
$(".portlet").on("mouseup", function() {
lastPosition = $(this).position();
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With