jQuery sortable - getting the new and original index

The jQuery sortable plugin allows us to give our users that drag 'n drop experience they all love so much.

Often we need to sort items and POST the updated order to the server. One method of doing this is to call the toArray function that generates an ordered array of item id's within your list:

$("ul.media-grid").sortable('toArray')

So given the following html:

<ul>
    <li id="red">Red</li>
    <li id="green">Green</li>
    <li id="blue">Blue</li>
</ul>

A call to toArray would produce:

["red", "green", "blue"]

We could then POST this to the server using ajax.

I tend to use this method for sorting smaller lists as it typically involves more work on the server (as we have to enumerate the entire collection).

Getting the new and original index of an individual item

We can achieve this by subscribing to the plugin's start and stop events. The following code demonstrates how we can use these events along with jQuery's data() method to POST the index values to the server:

var updateUrl;

self.sendUpdatedIndex = function ($item) {
    // increment by 1 as we're using 1 based index on server
    var startIndex = $item.data("startindex") + 1;
    var newIndex = $item.index() + 1;
    if (newIndex != startIndex) {
        $.post(
            updateUrl,
            { id: $item.attr("id"), oldPosition: startIndex, newPosition: newIndex }
        );
    }
}

pub.init = function (url) {

    updateUrl = url;

    $("ul.project-grid").sortable({
        start: function (event, ui) {
            $(ui.item).data("startindex", ui.item.index());
        },
        stop: function (event, ui) {
            self.sendUpdatedIndex(ui.item);
        }
    }).disableSelection();
}

The key point here is the item's index() method that returns its current index. In this example we check the original index against the new index and only POST to the server if it has changed.


Ben Foster

About Me

I'm a software engineer and aspiring entrepreneur with 12+ years experience in the tech industry and have worked with startups and SMB’s in areas such as healthcare, recruitment and e-commerce (I even worked in enterprise, once). I founded my first startup Fabrik in 2011.

I now head up the engineering team at Checkout.com. If you're interested in working in an exciting fin-tech company, drop me a message on Twitter.

Creative Commons Licence