Row reordering after sorting

Row reordering after sorting

BloodlexBloodlex Posts: 5Questions: 1Answers: 0

Hello :smile: ,

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 :smile:

This question has an accepted answers - jump to answer

Answers

  • kthorngrenkthorngren Posts: 12,761Questions: 25Answers: 3,002

    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

  • BloodlexBloodlex Posts: 5Questions: 1Answers: 0

    Hey :smile:

    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:

    • Order by name, ascending
    • Try to move 'Apple' one row down so it swaps places with 'Boeing'

    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 :smile:

    Example URL: live.datatables.net/jitalezu/2/edit

    Kuba

  • kthorngrenkthorngren Posts: 12,761Questions: 25Answers: 3,002

    The only issue that it seems I have is that internally DataTables doesn't update this column in its cache

    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.

    but as I'm trying it out I have a feeling it doesn't work as expected sometimes

    I haven't noticed any issues with reordering the rows.

    Kevin

  • kthorngrenkthorngren Posts: 12,761Questions: 25Answers: 3,002
    edited January 2018

    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

  • BloodlexBloodlex Posts: 5Questions: 1Answers: 0
    edited January 2018

    Hey @kthorngren, thank you very much :smile:

    I created a new example for you which updates the row data directly for the '#' column:
    http://live.datatables.net/woqujumi/1/edit

    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.

    Here is a second example:
    http://live.datatables.net/fuwoyili/1/edit

    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

  • kthorngrenkthorngren Posts: 12,761Questions: 25Answers: 3,002

    That first one is not the correct example, sorry :smile:

    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 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

  • BloodlexBloodlex Posts: 5Questions: 1Answers: 0
    edited January 2018

    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.

    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 :(

  • kthorngrenkthorngren Posts: 12,761Questions: 25Answers: 3,002
    Answer ✓

    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 the row-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. Last row-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

  • BloodlexBloodlex Posts: 5Questions: 1Answers: 0

    Hello again :smile:

    Ok, this sounded like a fun challenge. Think I have it woking the way you want:
    http://live.datatables.net/hifomuqa/2/edit

    THANK YOU VERY MUCH @kthorngren !!! :smiley:

    This is exactly the way I wanted it to be :) You're awesome :)

    Anyway there is plenty of cryptic comments and console output if you are interested in understanding how it works.

    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 :smile: I'm so happy that you managed to do it, once again big big thanks :smile:

    Kuba

This discussion has been closed.