I'm working with a default jQueryUI connected sortable list. But i need some (as far as i know) not default functionality. I'm hoping someone here knows an easy way to accomplish what i want (maybe with a plugin?). I coulddn't find any direct solutions.
Like i said, i'm working with a default connect sortable: http://jsfiddle.net/KLvdn/
This all works. I can drag and drop items from one list to another. But what i actually want is to be able to drag an item from one list, drop it ontop of another item in the other list and make them swap.
So in steps;
- I drag "Item 1" from the left list
- I drop it onto "Item 3" from the right list
- "Item 1" will be positioned on the place of "Item 3"
- "Item3" will be moved to the left list on the spot where "Item 1" was.
Is this already possible somehow?
My solution
This is what i did eventually.
I needed a way to drop an item from one list ontop of an item in another list. When dropped, the item underneath it should automatically be placed in the other list. Thus, wapping the two items.
First i added three properties to my connected list:
var _index = null;
$("#field-mylist, #test-mylist").sortable({
connectWith: ".mylist",
placeholder: 'ui-placeholder', // <-- VERY IMPORTANT
change: function (event, ui) {
markForReplacement('mylist', ui);
},
update: function (event, ui) {
updateConnectedLists('mylist');
}
}).disableSelection();
And the two functions that are called by the change and update event:
function markForReplacement(position, ui) {
var total = 0;
$('#field-' + position + ' .player').each(function (index) {
$(this).removeClass("selected-item");
total++;
});
var index = ui.placeholder.index();
if (total < (index + 2)) {
$('#field-' + position + ' div:eq(' + (index - 1) + ')').addClass("selected-item");
_index = (index - 1);
} else {
$('#field-' + position + ' div:nth-child(' + (index + 2) + ')').addClass("selected-item");
_index = (index + 2);
}
}
function updateConnectedLists(position) {
if (_index === null)
return;
$('#field-' + position + ' div:nth-child(' + (_index) + ')').insertAfter($("#test-" + position + " .player"));
_index = null;
// Reset class styles
$('#test-' + position + ' .player').each(function (index) {
$(this).removeClass("selected-item");
});
$('#test-' + position).sortable('refresh');
}
One more important thing to add is the following CSS style:
.ui-placeholder {
float: left;
}
.selected-item{
border-color: #FF6600 !important;
}
With ui-placeholder you can actually place an item ontop of another item (before releasing it). The .selected-item class gives a border to the element that is about to be moved to the other list (so the underlaying item).