Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Put new rows at the specific position of the jQuery datatable

DEFAULT
I create ajax datatable, which rows are sometimes filled by json in the end of table: jsfiddle and sometimes in the top of table. It depends of time of ajax response.

RECOMMENDED OUTPUT
I have two input jsons from two different sources and output is this table:

<table>
    <tr><td>1</td><td>2</td><td>3</td></tr>
    <tr><td>1</td><td>2</td><td>3</td></tr>
    <tr><td>1</td><td>2</td><td>3</td></tr>
    ...
    <tr><td>1</td><td>2</td><td>3</td></tr>
    <tr><td>1</td><td>2</td><td>3</td></tr>
    <tr><td>8</td><td>7</td><td>6</td></tr> <!-- inserted row-->
    <tr><td>8</td><td>7</td><td>6</td></tr> <!-- inserted row-->
    <tr><td>8</td><td>7</td><td>6</td></tr> <!-- inserted row-->
    <tr><td>8</td><td>7</td><td>6</td></tr> <!-- inserted row-->
    <tr><td>1</td><td>2</td><td>3</td></tr>
    <tr><td>1</td><td>2</td><td>3</td></tr>
    ...
    <tr><td>1</td><td>2</td><td>3</td></tr>
</table>

Rows from 2. json are inserted in table (created from 1. json) to specific position. This position is constant, lengths of 1. and 2. json data are constant.

FIRST SOLUTION
I have to add first column containing a number and sort the datatable descending by it - jsfiddle. I can hide first column jsfiddle, but I rather use custom function, because it doesn't work in IE8.

var t = $("#tab1").DataTable({
    "ajax": "data1.json",
    columnDefs: [
         { className: "hide", "targets": [ 0 ] },
         ], 
    "columns": [
        { "data": "id"},
        { "data": "cat1"},
        { "data": "cat2"},
        { "data": "cat3"}
    ]
});

$.ajax({
    type: "GET",
    url: "data2.json",
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function (response) {
        t.rows.add(response.data); 
        t.draw();
    }
  });

IDEA - CUSTOM FUNCTION
I try to create custom function rows.addinposition(rows, position), but it works as function rows.add().
I copied and modified function rows.add found in jquery.dataTables.js at line 7879, I changed out.push() to out.splice() splice docs.

I know, it is not recommended, better is extend datatables api...

_api_register( 'rows.addinposition()', function ( rows, position ) {
    var newRows = this.iterator( 'table', function ( settings ) {
            var row, i, ien;
            var out = [];

            for ( i=0, ien=rows.length ; i<ien ; i++ ) {
                row = rows[i];

                if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
                    //ROWS.ADD USE OUT.PUSH
                    //out.push( _fnAddTr( settings, row )[0] );
                    //CHANGED TO OUT.SPLICE
                    out.splice( position, 0, _fnAddTr( settings, row )[0] );
                }
                else {
                    out.splice( position, 0, _fnAddData( settings, row ) );
                }
            }
            console.log(out);
            return out;

        }, 1 );

    // Return an Api.rows() extended instance, so rows().nodes() etc can be used
    var modRows = this.rows( -1 );
    modRows.pop();
    modRows.push.apply( modRows, newRows.toArray() );

    return modRows;
} );    

It would be great if you could help me.

I found similar questions:

  • SO link: function fnAddData() in version 1.9 Datatables
  • SO link - add multiply rows to end of datatable
  • SO link - no answer
  • datatables forum link - old version, no answer (I think)

EDIT
Thank you davidkonrad, but I test it in jsfiddle, and I found 2 problems:

  • ordering is wrong 2.,1., not 1.,2. - I think easy problem
  • sometimes this added rows are on the top of table, sometimes in right position. Randomly. - maybe big problem

I debug it in jsfiddle and its behaviour is very strange:

console.log('rowCount = '+rowCount);

if rows are on the top (bad position) return:

rowCount = 0
rowCount = 1

and for didn't loop, because firebug doesn't show var i.

if they are in good position, return:

rowCount = 5
rowCount = 6

and for looped and var i returned in this example:
1. loop:

i = 5 
i = 4 
i = 3

2.loop:

i = 6 
i = 5 
i = 4 
i = 3

Did i missed something? Why order is strange?

like image 963
jezrael Avatar asked Jul 28 '15 08:07

jezrael


People also ask

How to add a row to specific index in jquery dataTable?

dataTables holds its rows in an indexed array, and there is no API methods for adding a new row at a specific index or change the index() of a row. That actually makes good sense since a typical dataTable always is sorted / ordered or filtered on data, not the static index.

How do I add a row to a dataTable?

To add a new row, declare a new variable as type DataRow. A new DataRow object is returned when you call the NewRow method. The DataTable then creates the DataRow object based on the structure of the table, as defined by the DataColumnCollection.

How append Ajax response to dataTable?

First store the dataTable object in a variable, var dataTable = $("#viewTable"). DataTable(); Then on ajax success, use dataTable.


1 Answers

You do not need to modify the source code directly, use dataTable.Api.register instead :

jQuery.fn.dataTable.Api.register('row.addByPos()', function(data, index) {     
    var currentPage = this.page();

    //insert the row  
    this.row.add(data);

    //move added row to desired index
    var rowCount = this.data().length-1,
        insertedRow = this.row(rowCount).data(),
        tempRow;

    for (var i=rowCount;i>=index;i--) {
        tempRow = this.row(i-1).data();
        this.row(i).data(tempRow);
        this.row(i-1).data(insertedRow);
    }     

    //refresh the current page
    this.page(currentPage).draw(false);
});

The above function (or plugin) inserts the row, and then "moves" the row up to its desired position simply by swapping content -> read more detailed explanation.
Demo -> http://jsfiddle.net/p4wcfzfe/

Since the plugin adds a function to the general API, the plugin should be declared before initialization of any dataTable using that function.

{ plugin declaration }
var table = $("#example").DataTable();
table.row.addByPos([data], 1);

NB: Your "first solution" should work in IE8 too, try to remove the trailing commas.

like image 84
davidkonrad Avatar answered Sep 22 '22 12:09

davidkonrad