Using MooTools 1.2 For Drag, Drop, Sort, Save
My customers love being able to control their website’s content so I build a lot of administrative control into their website. One administrative control I frequently build is a News control. I allow the customer to add, edit, delete, and sort news items. My customers especially love sorting their articles because of the fashion of which they can sort: drag and drop. Here’s how I do it.
The MySQL Table
| id | title | sort_order |
| 1 | Article 1 | 1 |
| 2 | Article 2 | 2 |
| 3 | Article 3 | 3 |
| 4 | Article 4 | 4 |
| 5 | Article 5 | 5 |
| 6 | Article 6 | 6 |
My news table contains more fields but these are the important fields per this example.
The PHP / XHTML
<?php
$query = 'SELECT id, title FROM test_table ORDER BY sort_order ASC';
$result = mysql_query($query,$connection) or die(mysql_error().': '.$query);
if(mysql_num_rows($result)) {
?>
<p>Drag and drop the elements below. The database gets updated on every drop.</p>
<div id="message-box"><?php echo $message; ?> Waiting for sortation submission...</div>
<form id="dd-form" action="<?php echo $_SERVER['REQUEST_URI']; ?>" method="post">
<p><input type="checkbox" value="1" name="auto_submit" id="auto_submit" <?php if($_POST['auto_submit']) { echo 'checked="checked"'; } ?> /> <label for="auto_submit">Automatically submit on drop event</label></p>
<ul id="sortable-list">
<?php
$sort_order = array();
while($item = mysql_fetch_assoc($result))
{
echo '<li class="sortme" rel="',$item['id'],'">',$item['title'],'</li>';
$sort_order[] = $item['sort_order'];
}
?>
</ul>
<br />
<input type="hidden" name="sort_order" id="sort_order" value="<?php echo implode($sort_order,'|'); ?>" />
<input type="submit" name="do_submit" value="Submit Sortation" class="button" />
</form>
<?php } else { ?>
<p>Sorry! There are no items in the system.</p>
<?php } ?>
We query the database to get every news item. What’s extremely important is that the query sorts the items by their original sort order. We set the “rel” attribute equal to the article’s ID and the list item’s text to the article title.
The CSS
#sortable-list { padding:0; }
li.sortme { padding:4px 8px; color:#000; cursor:move; list-style:none; width:500px; background:#ddd; margin:10px 0; border:1px solid #999; }
#message-box { background:#fffea1; border:2px solid #fc0; padding:4px 8px; margin:0 0 14px 0; width:500px; }
I use the above CSS to format the news items so that the customer knows each news item may be dragged. None of the CSS is essential to this system.
The MooTools Javascript
/* when the DOM is ready */
window.addEvent('domready', function() {
/* create sortables */
var sb = new Sortables('sortable-list', {
/* set options */
clone:true,
revert: true,
/* initialization stuff here */
initialize: function() {
},
/* once an item is selected */
onStart: function(el) {
el.setStyle('background','#add8e6');
},
/* when a drag is complete */
onComplete: function(el) {
el.setStyle('background','#ddd');
//build a string of the order
var sort_order = '';
$$('#sortable-list li').each(function(li) { sort_order = sort_order + li.get('rel') + '|'; });
$('sort_order').value = sort_order;
//autosubmit if the checkbox says to
if($('auto_submit').checked) {
//do an ajax request
var req = new Request({
url:'',
method:'post',
autoCancel:true,
data:'sort_order=' + sort_order + '&ajax=' + $('auto_submit').checked + '&do_submit=1&byajax=1',
onRequest: function() {
$('message-box').set('text','Updating the sort order in the database.');
},
onSuccess: function() {
$('message-box').set('text','Database has been updated.');
}
}).send();
}
}
});
});
We use Moo 1.2’s Sortables plugin class to select all element within the list and make them sortable (drag and drop). Every time the sort order is changed, the hidden “sort_order” element is built and reset using a “|” as a separator. If the checkbox is checked, an ajax call is made to update the sort order in the database. Otherwise, the regular form submission via submit button will also save the sortation.
The “Header” PHP / MySQL
/* on form submission */
if(isset($_POST['do_submit']))
{
/* split the value of the sortation */
$ids = explode('|',$_POST['sort_order']);
/* run the update query for each id */
foreach($ids as $index=>$id)
{
if($id != '')
{
$query = 'UPDATE test_table SET sort_order = '.$index.' WHERE id = '.$id;
$result = mysql_query($query,$connection) or die(mysql_error().': '.$query);
}
}
/* now what? */
if($_POST['byajax']) { die(); } else { $message = 'Sortation has been saved.'; }
}
The header is where the new sort order is commited. We split the “sort_order” form value by the “|” and perform a query for each item to update its order. Lastly, if the “byajax” flag is sent, we just die out the PHP script — if not, we continue to load the page.
Hot system, right? Check out the example. Dragging and dropping is by far the fastest way to sort a list of items. What are your thoughts? Have any ideas for improvements?

this is EXACTLY what i was looking for, thanks.