0

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).

w00
  • 26,172
  • 30
  • 101
  • 147

1 Answers1

1

You can check this plugin for swap though there online demo seem to be down.

Disclaimer I haven't tried this plugin myself.

This post on SO is on the same lines.

This can be helpful too to get the index of element moved.

Community
  • 1
  • 1
mprabhat
  • 20,107
  • 7
  • 46
  • 63
  • I found that one too and also noticed it wasn't working anymore. I actually assumed it was outdated or something. But i'll give it a try anyway. Maybe it still works. – w00 Jun 05 '12 at 10:31
  • hope it works for you, also updated my post with similar post about swap – mprabhat Jun 05 '12 at 10:36
  • The "swap" plugin wasn't working for me after all. I needed something more custom. But i finally got it working. I used some code from one of the links you provided. So i'll just mark your answer as best since you did help me with that :-) --- I'll also try to edit my opening post and add what i did. Maybe it will be of some help for someone else in the future. – w00 Jun 05 '12 at 13:05