Drag-Drop table rows with jQuery sortable
Drag-Drop table rows with jQuery sortable
sronsiek
Posts: 52Questions: 11Answers: 0
Hi,
I've managed to implement drag-drop of table rows using jquery sortable,
but it seems very much like a hack to me.
Basically jquery sortable provides all the DOM changes in the table, the row
is visibly moved, but the DataTables internals are not updated, so the next
sort / draw operation (required for instance to re-apply the zebra striping etc)
will undo the drag-drop move. I've managed to overcome this in a very crude
algorithm, by cloning the entir aoData structure, then looping through the rows
writing the re-ordered data in the cloned structure - and finally replacing the
aoData with the the modified version and re-drawing the table with fnDraw.
This code looks as follows:
[code]
j(function() {
j("#example tbody").sortable({
opacity: 0.6,
cursor: 'move',
update: function(ev, ui) {
var oSettings = oTable.fnSettings();
var clonedData = oSettings.aoData.slice();
j('#example tbody tr').each(function(i)
{
var startPos = oTable.fnGetPosition(this);
// alert( "i: " + i + " startPos: " + startPos )
clonedData[i] = oSettings.aoData[startPos];
clonedData[i]._iId = i;
// App specific - first table col contains an incremental count which needs to be refreshed after a move
// Without cloning hack - do this with fnUpdate()
clonedData[i].nTr.cells[0].innerHTML = i+1;
clonedData[i].nTr.cells[0].innerText = i+1;
})
oSettings.aoData = clonedData;
oTable.fnDraw();
}});
});
[/code]
Can you advise:
- is this method safe to use?
- is there a clean way of re-numbering the aoData array indexes?
I've managed to implement drag-drop of table rows using jquery sortable,
but it seems very much like a hack to me.
Basically jquery sortable provides all the DOM changes in the table, the row
is visibly moved, but the DataTables internals are not updated, so the next
sort / draw operation (required for instance to re-apply the zebra striping etc)
will undo the drag-drop move. I've managed to overcome this in a very crude
algorithm, by cloning the entir aoData structure, then looping through the rows
writing the re-ordered data in the cloned structure - and finally replacing the
aoData with the the modified version and re-drawing the table with fnDraw.
This code looks as follows:
[code]
j(function() {
j("#example tbody").sortable({
opacity: 0.6,
cursor: 'move',
update: function(ev, ui) {
var oSettings = oTable.fnSettings();
var clonedData = oSettings.aoData.slice();
j('#example tbody tr').each(function(i)
{
var startPos = oTable.fnGetPosition(this);
// alert( "i: " + i + " startPos: " + startPos )
clonedData[i] = oSettings.aoData[startPos];
clonedData[i]._iId = i;
// App specific - first table col contains an incremental count which needs to be refreshed after a move
// Without cloning hack - do this with fnUpdate()
clonedData[i].nTr.cells[0].innerHTML = i+1;
clonedData[i].nTr.cells[0].innerText = i+1;
})
oSettings.aoData = clonedData;
oTable.fnDraw();
}});
});
[/code]
Can you advise:
- is this method safe to use?
- is there a clean way of re-numbering the aoData array indexes?
This discussion has been closed.
Replies
Having said that - nice solution to a non-trivial problem :-)
Allan
Sorry for the delay in replying - order of rows in DataTables is 100% done by the sorting that is applied to the table. So for example if you click on a column header or call fnSort(). So drag and drop rows is entirely possible, you just need to have the drop event handler update the sorting information that is being applied to the table and then redraw the table (fnUpdate would be the key API method for this). It gets slightly complicated if you want to keep the user ability to sort columns, since you then have 2D sorting and you need to decide which one takes priority.
I'm afraid I don't have an example of code which does this, but I think the best way of doing it would be to write a plug-in for DataTables: http://datatables.net/blog/Creating_feature_plug-ins .
Regards,
Allan