Using Jquery UI sortable to sort table rows

Suppose you have a list of items arranged in a table and you want to change the sorting order of the items - Jquery UI has a wonderful and easy to use plugin for this - know as Sortable. The sortable plugin allows us to do the sorting using drag and drop with mouse click. In this article we will see the sortable plugin in action using drag and drop and also using separate UP / DOWN buttons.

Consider the following html markup for our sample table:

<table class="table table-striped">
    <tbody id="tabledivbody">
        <tr class="sectionsid" id="sectionsid_1">
                <td>Overview</td>
                <td><a href="javascript:void(0)" class="movedownlink">
<span class="glyphicon glyphicon-arrow-down"></span></a></td>
                <td></td>
        </tr>
        <tr class="sectionsid" id="sectionsid_2">
                <td>History behind OOPS</td>
                <td><a href="javascript:void(0)" class="movedownlink" >
<span class="glyphicon glyphicon-arrow-down"></span></a></td>
                <td><a href="javascript:void(0)" class="moveuplink" >
<span class="glyphicon glyphicon-arrow-up"></span></a></td>
                <td></td>
        </tr>
        <tr class="sectionsid" id="sectionsid_3">
                <td>Summary</td>
                <td><a href="javascript:void(0)" class="moveuplink" >
<span class="glyphicon glyphicon-arrow-up"></span></a></td>
                <td></td>
        </tr>
    </tbody>
</table>

This markup when redered looks like this -
sorting table rows using jquery ui sortable - 1
Now, as you can see that there are 3 items in the table and if needed we can rearrange and change their order using the up / down arrow keys or simply dragging one row and placing over another row. It may look fancy and tough, but it is actually very easy to achieve the same. Just read on...

Step 1: Include the following scripts for Jquery UI Sortable to work:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css" />
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>


Step 2: Following javascript code is required to make the table rows sortable:


    $("#tabledivbody").sortable({
items: "tr",
cursor: 'move',
opacity: 0.6,
update: function() {
sendOrderToServer();
}
});

function sendOrderToServer() {
var order = $("#tabledivbody").sortable("serialize");

$.ajax({
type: "POST", dataType: "json", url: "/path/to/updateorder/script",
data: order,
success: function(response) {
if (response.status == "success") {
window.location.href = window.location.href;
} else {
alert('Some error occurred');
}
}
});
}



To make the rows sortable, you need to use table body (tbody) as the selector. jQuery UI Sortable plugin also provides a way to let us know the current order of the rows. For this, the sortable plugin expects us to provide them some info in the form of id attributes of the rows. See - id="sectionsid_1" in our html example. Once you get this step correct, you can get the current order of items in a serialized array using - $("#tabledivbody").sortable("serialize") statement. This ordering information can also be passed on to the server to be updated in a Database too. Here in this example we are using an AJAX call to our backend so that as soon as the order changes we update the same in our database and once the response has come back from server, we refresh the page to display the recently updated order from the Database. The POST data may look like - sectionsid[]=1&sectionsid[]=2&sectionsid[]=3

Step 3: processing order array at the backend:

The following is an example in php to demonstrate how to handle this ordering information and store it in Database:

        $sectionids = $_POST('sectionsid');
$count = 1;
if (is_array($sectionids)) {
foreach ($sectionids as $sectionid) {
$query = "Update sections SET display_order = $count";
$query .= " WHERE id='".$sectionid."'";

// your DB query here

$count++;
}

echo '{"status":"success"}';
} else {
echo '{"status":"failure", "message":"No Update happened. Could be an internal error, please try again."}';
}

The above code assumes that you have a column - 'display_order' to maintain order for each table row item in database table.

How to handle separate UP / DOWN arrow keys with sortable plugin:

Add the following javascript code to reorder the table rows using individual buttons:

    $(".moveuplink").click(function() {
$(this).parents(".sectionsid").insertBefore($(this).parents(".sectionsid").prev());
sendOrderToServer();
});

$(".movedownlink").click(function() {
$(this).parents(".sectionsid").insertAfter($(this).parents(".sectionsid").next());
sendOrderToServer();
});


What is happening here, is that as soon as an arrow button is clicked(whether it is up or down identified by their classes - moveuplink and movedownlink respectively) - the rows are dynamically updated in the table DOM hierarchy. And as before, upon clicking of these buttons the information is again sent back to the backend, where the same can be updated in the Database.

That's all what is needed to get the table rows sorted either by drag and drop or by clicking specific buttons.

PS: While working with this, you might observe a wierd issue while dragging a table row. Sometimes, the width of the row gets collapsed and the row looks shrinked than the actual width. The issue can be fixed(courtsey ) by providing a custom helper callback as follows:

    var fixHelper = function(e, ui) {
ui.children().each(function() {
$(this).width($(this).width());
});
return ui;
}

$("#tabledivbody").sortable({
------
helper: fixHelper,
});


comments powered by Disqus