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:
fnAddData()
in version 1.9 DatatablesEDIT
Thank you davidkonrad, but I test it in jsfiddle, and I found 2 problems:
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?
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.
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.
First store the dataTable object in a variable, var dataTable = $("#viewTable"). DataTable(); Then on ajax success, use dataTable.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With