I put together a (quite elegant) solution :)There is very little to do - both in terms of setup and implementation, and (unlike most implementations) the method even works when table paging is in operation!The only requirement for tables using this feature is a suitably-sized unsigned INT field which is indexed and has a default value of AUTO_INCREMENT - I prefer to name this field ‘Order’, but you can use any name you wish. Here is an example from one of my tables (I find that ‘smallint’ is quite sufficient, but you r can use ‘int’ if you prefer):Order smallint(5) unsigned NOT NULL AUTO_INCREMENTSo, now we can start implementing the feature…Begin by adding jquery-ui to your project if it is not already included. You can download it from jqueryui.com/download/
I saved the plug-in to the existing PHPM ‘jquery’ folder, so you will need to adapt the path if you save it somewhere different for your project.Begin by adding this to Server Events > Global > All Pages > Page_Head …Now add this to Server Events > Global > All Pages > Global Code …function GetKeyField($scope) {
foreach ($scope as $key => $subkey) {
if (is_object($subkey) && isset($subkey->IsPrimaryKey) && $subkey->IsPrimaryKey)
return ($key);
}
}Next, add this to Server Events > Other > Index Page > Page_Load …
if (isset($_POST['table']) && isset($_POST['field']) && isset($_POST['order']) && isset($_POST['data'])) {
$table = $_POST['table'];
$field = $_POST['field'];
$order = $_POST['order'];
$data = $_POST['data'];
if (empty($table) || empty($field) || !is_array($data) || count($data) == 0)
die('Incompatible arguments');
$fields = array();
$orders = array();
$offset = count($data);
foreach ($data as $row) {
$pair = explode('{||}', $row);
$fields[] = $pair[0];
$orders[] = $pair[1];
}
for ($index = 0; $index < count($data); $index++) {
Execute("UPDATE `{$table}` SET `{$order}` = {$orders[$index]} WHERE `{$field}` = '{$fields[$index]}'");
}
die();
}
Finally, add this to Client Scripts > Global > Pages with header/footer > Global Code …function tableDnD(table, field, order = ‘Order’) {
$(‘table’).find(‘tbody’).addClass(‘sortable-table’);
$('.sortable-table').sortable({
delay: 150,
stop: function() {
var lowest = 1000000;
$('.sortable-table tr').each (function() {
$(this).find('td').each (function() {
if ($(this).attr('data-name') == order)
lowest = Math.min(lowest, parseInt($(this).find(':only-child:last').text()));
});
});
var index = 0;
var data = new Array();
$('.sortable-table tr').each (function() {
$(this).find('td').each (function() {
if ($(this).attr('data-name') == field)
data.push($(this).text().replace(/[\t\n]+/g, '') + '{||}' + (lowest + index));
else if ($(this).attr('data-name') == order)
$(this).find(':only-child:last').html(lowest + index);
$(this).removeClass('ew-table-last-row');
});
if (index === 0 || !!(index && !(index % 2)))
$(this).removeClass('ew-table-alt-row');
else
$(this).addClass('ew-table-alt-row');
index++;
});
$('.sortable-table tr:last').each (function() {
$(this).find('td').each (function() {
$(this).addClass('ew-table-last-row');
});
});
$.ajax({
url: 'index.php',
type: 'post',
data: {table:table, field:field, order:order, data:data},
success: function(response) {
}
});
}
});
}…and that’s it!To activate the feature, go to Client Scripts > Table-Specific > List Page > Startup Script and add this …tableDnD(‘<?=CurrentPage()->TableName?>’, ‘<?=GetKeyField(CurrentPage())?>’);** If you named your ‘Order’ field something different then use:
tableDnD(‘<?=CurrentPage()->TableName?>’, ‘<?=GetKeyField(CurrentPage())?>’, ‘NameOfYourOrderField’);Now just rebuild your project and have fun