So I recently had to create a sortable table using jQuery UI. I figured it should be easy because there’s a jQuery API specifically for making things sortable and there were plenty of Google hits on “jquery ui sortable table.”
But, it turns out, while it’s easy to find information on how to make things sort visually, it’s very difficult to find information on how to hook into the events so that you might actually do something useful with a sortable table.
I’ll spare you some of the suspense. To make a table sortable, just encase the rows you want sortable in a <tbody> tag, like this:
<table width="100%" id="contents_table"> <thead> <tr> <td class="contents_header"></td> <td class="contents_header">Name</td> </tr> </thead> <tbody class="sortable_table"> <tr class="sortable_row" id="123"> <td><span class="ui-icon ui-icon-arrowthick-2-n-s"></span> <input type="hidden" name="old_order_123" id="old_order_123" value="0"/> <input type="hidden" name="new_order_123" id="new_order_123" value="0"/> </td> <td class="contents_value">Some Stuff</td> </tr> <tr class="sortable_row" id="456"> <td><span class="ui-icon ui-icon-arrowthick-2-n-s"></span> <input type="hidden" name="old_order_456" id="old_order_456" value="1"/> <input type="hidden" name="new_order_456" id="new_order_456" value="1"/> </td> <td class="contents_value">Some More Stuff</td> </tr> </tbody> </table>
And in your document ready function make sure you make it sortable:
<script>
$(document).ready(function() {
$( "#contents_table tbody.sortable_table" ).sortable({
update: handle_resort
});
$( "#contents_table tbody.sortable_table" ).disableSelection();
});
</script>
I won’t get too much into how that works because there’s plenty to find on Google. But now, how do you know what rows were sorted and what the new order is? After much fiddling, I came up with this:
function handle_resort(event, ui){
var i = 0;
jQuery("tbody tr.sortable_row").each(function(i){
var row = $(this).get()[0]; //this is the <tr> element
var inputId = "new_order_" + row.id;
var input = jQuery("#"+inputId);
var inputElem = input.get()[0];//this is the <input name="new_order_nnn"/> element
inputElem.value = i;
i = i + 1;
});
}
Maybe it’s because I’m a jQuery newbie, but I still have no idea what you use “event” or “ui” for. But they are shown on every piece of example code out there and then summarily ignored. This is one of my only frustrations with dynamic languages: if an API developer doesn’t provide enough documentation and hands you some objects, you have no idea what to do with them.
So, instead I gave all my rows a class that was easy to find. Then, I grab them all and iterate through them in order. I use a hidden <input> tag to stash this order for future reference when the user submits the form. What examples there are out there instead make an AJAX call and serialize the rows, but I didn’t want so many round trips to my server for something as simple as resorting things.
There, I hope that saves you the hour and a half I had to spend. Enjoy.
