Looking for code example to 'splice' row into table.

Looking for code example to 'splice' row into table.

st9400st9400 Posts: 5Questions: 1Answers: 0

I can't seem to figure out how to insert a row into a table using the splice API function. It seems very simple, but I must be doing something fundamentally wrong. My code is something like this:

$(document).ready(function () {
    
    $('#example').DataTable( {
        "lengthMenu": [ [4, 10, 25, -1], [4, 10, 25, "All"] ],
        "ordering": false,  // don't allow columns to be sorted.
        select: true,  // enable the (row) Select module functionality.
        select: 'single',  // only allow one row to be selected at a time.
        dom: 'B<"clear">lftip',  // https://datatables.net/reference/option/dom
        buttons: [ ]  // no custom buttons needed, (but this line is required).
    } );

    var table = $('#example').DataTable();

    table.button().add( 1, {
        action: function ( e, dt, button, config ) {
            var idx = dt.row('.selected').index();
            dt.splice(idx, 0, <something>);  // <--------
            dt.draw();
        },
        text: 'Insert row'
    } );
});

I've tried all kinds of things for <something>, and many different ways to invoke the splice() call, but nothing seems to work. To eliminate the <something> issue, I even tried hard-coding a 'remove' using dt.splice(1,0);, but that doesn't even work.

In another button handler (not shown), I implemented a row 'remove', and that works flawlessly:

dt.rows('.selected').remove().draw();

If someone could point me to a simple splice() example or point to an improper construct in my code, I would much appreciate it!

This question has an accepted answers - jump to answer

Answers

  • kthorngrenkthorngren Posts: 21,172Questions: 26Answers: 4,923

    The proper way to insert a row into a Datatable is to use the row.add() API. The row will be inserted and sorted into the table. Why are you trying to use splice()?

    Kevin

  • st9400st9400 Posts: 5Questions: 1Answers: 0

    Thanks, Kevin, for the fundamental mind shift. I'm using row.add() successfully to build my table. But, as far as I could tell, it only appends to the end. I didn't come across anything in your docs and forum that suggested what the syntax would be to insert that somewhere in the middle. But I will start hunting and experimenting! If you could post a one-line example, that would help.

    That said, why does splice() not work? And what's its intended purpose (or typical use)?

  • kthorngrenkthorngren Posts: 21,172Questions: 26Answers: 4,923
    Answer ✓

    But, as far as I could tell, it only appends to the end.

    The row will be inserted and shown in the table based on the current sorting and searching applied to the table. Built a simple example to show this here:
    http://live.datatables.net/ridimodi/1/edit

    It will add Apple which will end up being the second row based on sorting.

    That said, why does splice() not work?

    The splice() method is meant for arrays not tables. Plus Datatables doesn't now know about changes to tables that are made without using Datatables API's.

    Kevin

  • st9400st9400 Posts: 5Questions: 1Answers: 0

    Thanks much for the clarifications. I guess I got off on the wrong track because of frequent comments in the manuals like "DataTables API instances are 'array like'," so I maybe read a little too much into that and thought I might be able to regard the entire table as an array of rows.

    Because I'm not using sorting —(in fact, I have it disabled with "ordering": false) — nor is there anything in my data that could be keyed on for sorting, the order that gets rendered, it appears, is the order in which the rows were added to the table. That is also the desired order except for the occasional times when an error is found and a user wants to go back and correct a row — (delete it, move it, add a missing one, etc.).

    To that end, I was able to come up with a simple row().insert() workaround that first appends the new row to the end with row.add(), then, starting at the row insertion point, one-by-one removes each row and re-adds it, thus moving each of them down, in order, past the "inserted" row, as shown below, (stripped down for simplicity).

    table.button().add( 1, {
        action: function ( e, dt, button, config ) {
            var idx = dt.row('.selected').index();
            console.log('Selected row: ' + idx);
            
            var len = dt.column( 0 ).data().length;  // length of table (before paste).        
            // paste (append) the previously cut row to the end of the table.
            dt.row.add(rsel_last_cut[0]);
            
            // now move it into place by removing and re-adding other rows above it.
            var rr;
            for (ii=idx ; ii<len ; ii++) {  // loop for selected row and all below it.
                rr = dt.row( idx/*sic*/ ).data();    // preserve data of this row.
                dt.row(      idx/*sic*/ ).remove();  // delete this row.
                dt.row.add(rr);  // append it to the end.
            }
            dt.draw();  // render changes.
        },
        text: 'Paste before'
    } );
    

    Some feedback on the manual pages: for much of my early reading, I conflated any discussion of selecting rows with a 'selector' with discussions of rows selected by, say, a user's mouse click selection (with the Select extension module installed). Perhaps you want to sprinkle some clarifications here and there so folks don't go too far down the track thinking they're the same things like I did.

    But, overall, I think you guys have done some great work! I'm looking forward to making more use of DataTables in the future!

  • kthorngrenkthorngren Posts: 21,172Questions: 26Answers: 4,923
    edited June 2020

    Interesting solution. Not sure if it would be more efficient or save time but you could use destroy(), insert the row at the top of the table using jQuery then reinitialize datatables. Here is an example:

    EDIT: Updated example:
    http://live.datatables.net/xufupavu/2/edit

    Kevin

  • st9400st9400 Posts: 5Questions: 1Answers: 0

    Two issues with this use of destroy():

    1. It can only put my London colleague at the top of the list, that is, insert at the beginning, not randomly.
    2. It rebuilds the list from a hard-coded HTML set (which isn't the case for me).

    In that vein, though, I had looked into using rows().remove() to see if I could remove all items below the selected insertion point in one operation (and then maybe rows.add() to add them back in in one operation), but it wasn't apparent to me that I could specify a row index range to either of the rows functions. I gathered that that was because there is no inherent order to the table, so an index 'range' could not be defined. Nonetheless, there's a concept of row indices with functions like table.rows('.selected').indexes(). And I was encouraged by the statement that "DataTables API objects are 'array like.' in that they inherent a lot of the abilities and methods of the Javascript Array type."

    But then I'd have to programmatically 'select' the subsequent rows before using remove(), and that would be no more elegant than my little one-by-one loop. However, if you were to support range selection with a selector-modifier, like, say, "3:7" or "3:end" or "var_start:var_end", that would make this task very simple.

    Steve

  • kthorngrenkthorngren Posts: 21,172Questions: 26Answers: 4,923

    Sorry, I misunderstood. Thought you wanted the inserted rows at the top. How are you basing where you want the rows inserted? Maybe there is a way to set it up to allow Datatables to handle the ordering based on how you are handling the order.

    Kevin

  • st9400st9400 Posts: 5Questions: 1Answers: 0

    With the Select extension installed, the user selects the row in the table as the insertion point. Then I have both a 'Paste before' and a 'Paste after' button (which do the same thing except for whether the selected row also gets removed and re-added). The ordering I use is simply the order that rows were entered by the user (and that's, of course, the order that's displayed as long as no sort logic is applied).

    Steve

This discussion has been closed.