Row reordering after sorting
Row reordering after sorting
Hello ,
I have a problem with reordering rows after sorting. I've read everything I could find on the web, but it doesn't seem to help me a bit or the solutions are hacks in most of the times for one of the older releases of DataTables.
So, the question is, how can I freely reorder rows after the table had been sorted? I guess it is not possible out of the box, while DataTables refuses to reorder the rows because it violates the column ordering. How can I override it and allow users to change the row order without sort column having impact on that behavior until the column is resorted again?
My table has no initial data - I'm adding it later after having called ajax request and using API method table.row().add(). The first column is a sequence column - I'm filling it with subsequent integer values. My initialization of rowReorder is presented below:
"rowReorder": {
dataSrc: 'sequence',
},
And how I'm adding new rows:
let count = 1;
data.forEach(function (i) {
table.row.add({
"sequence": i.id,
"#": count,
"name": i.names.pl,
}).node().id = i.id;
count++;
});
The second column should display just the number of row always starting from 1, I didn't use it as a sequence column to not to interfere with DataTables in any way regarding row reording.
Thanks in advance for any help in this matter.
And by the way DataTables is great thank you very much for it
This question has an accepted answers - jump to answer
Answers
I put your example here:
http://live.datatables.net/qofayowu/1/edit
I added the
row-reordered
to reset the table order to column 0 ascending. If I order the table by one of the other columns then reorder the table it looks correct. Is this what you are looking for?Kevin
Hey
Thanks a lot for your reply and for the example. I haven't thought of doing it that way, but as I'm trying it out I have a feeling it doesn't work as expected sometimes.
I cloned your example and add additional data that can demonstrate the issue comprehensively. Please do the following:
Maybe it has something to do with the place I'm dropping the row on or something like this? Because it doesn't work for me most of the time. Sometimes it seems a bit tricky because the other rows get swapped and not the ones I'm trying to.
I would also like the column '#' to always have incremented numbers no matter what the order is (so '#' column always maintains 1,2,3 etc.) and the sequence column is hidden to the end user and is just used internally by DataTables to properly swap rows. It should remain incrementally ordered (1,2,3...) even after sorting with every column or reordering.
The only issue that it seems I have is that internally DataTables doesn't update this column in its cache, so for instance after I had exported my table into .pdf or .xlsx I still get the wrong '#' order.
Thank you once again for the help I really appreciate that
Example URL: live.datatables.net/jitalezu/2/edit
Kuba
Correct, Datatables doesn't update the cache when updating the HTML directly. Normally you can use something like
rows().invalidate()
but it didn't seem to work in your case.I created a new example for you which updates the row data directly for the '#' column:
http://live.datatables.net/woqujumi/1/edit
Seems to work ok but note that when reordering the script will update the table 3 times as the row-reorder, search and order events are hit.
I haven't noticed any issues with reordering the rows.
Kevin
Here is a second example:
http://live.datatables.net/fuwoyili/1/edit
It eliminates the need for
rows().invalidate()
. I suspect this version will be more efficient since the Datatable data is directly updated removing the need to invalidate. But @allan can tell us for sure which is better.EDIT: One option to improve performance may be to update just the page displayed. You can use
page.info()
to get the page info to adjust '#' column starting number and just update the page displayed.Kevin
Hey @kthorngren, thank you very much
I've just tried the first example, but it doesn't work unfortunately on my computer, because the website hangs and I get "Maximum call stack size exceeded". I suppose it has something to do with multiple updates on the table that you mentioned.
I can run the second example without problems and if I don't apply any sorting it works awesome. However as I sort the table for example with the category column and drag a row it acts weirdly: for instance when I would like 'Apple' to be on the second position it jumps to the last or the third one out of the blue. I don't know if it is something that happens only for me as you say you don't have such problems?
As I see what how it acts right now on my machine, I think it tries to restore the default order and then moves the row instead of just moving the row without changing current row positions - it would be ideally that it just disables sorting (without changing content) as the row is being dragged and allows the positions to be freely set.
I really would like it finally to work as I've been struggling with it for a few days so far
for simplicity's sake, because it got overcomplicated a bit :
- when there is no sorting it should act like now, so we can freely change positions
- when there is sorting applied, on reorder it should disable sorting without changing content and allow us to change position as if there was no sorting ever applied
Kuba
That first one is not the correct example, sorry
I see, I was able to recreate this as well. I took out the
row-reordered
event and it seems to work better. Not sure why that is causing the problem but its probably a race condition with all the events fired. Maybe you don't need to reset the ordering back to column 0.Updated example:
http://live.datatables.net/fuwoyili/2/edit
Kevin
Ahh, now I see it insists on keeping the sort order (jumps back to the previous position as I release the mouse button) and doesn't let me to reorder any of the rows, it would be perfect if it just allowed me to do this, updated '#' accordingly and internal model so export data was coherent with dom
Ok, this sounded like a fun challenge. Think I have it woking the way you want:
http://live.datatables.net/hifomuqa/2/edit
RowReorder basically performs a data swap of the
rowReorder.dataSrc
column. In order for you to use the "#" column to keep the data sorted by other columns you need to do the same.Basically the example gets the original row indexes (probably not needed) and rowReorder indexes (both arrays) in the
row-reorder
event before reordering. In therow-reorderd
event it gets the new sequence array (rowReorder index). It uses the new sequence number to get the index of the matching number in the original sequence number array. This index + 1 will be the new "#" for that row. Lastrow-reorderd
sorts the table by the "#" column.I use booleans to keep the search and order events from updating the "#" column numbers if rowReorder already updated the column. I also have a boolean to stop the order event from updating the column if either rowReorder did or search. No point in updating the "#" column again if search as already do so. I looks like the order event is not needed as I don't see a case where the search event is not executed first.
Anyway there is plenty of cryptic comments and console output if you are interested in understanding how it works.
Kevin
Hello again
THANK YOU VERY MUCH @kthorngren !!!
This is exactly the way I wanted it to be You're awesome
Yes, of course I'm interested, because I've been struggling with it for so long. I'm analyzing the console output and your description to find out how it works right now
That was a challenge, indeed I'm so happy that you managed to do it, once again big big thanks
Kuba