After puzzling over this for a few hours, and looking everywhere for help, I now post here. My problem: the jQuery DataTable plugin's $(selector).DataTable() always returns an empty array.
To create this in minimal form, and using DataTables 1.10.7, applied to the
zero-config example
I find that var tableRef = $("#example").DataTable() returns [].
$("#example")
resolves as you would expect to
<table id="example" class="display dataTable" cellspacing="0" width="100%" role="grid" aria-describedby="example_info" style="width: 100%;">…</table>
with
$("#example tr").length // 12 rows
This old-style API works:
$("#browserTable").dataTable();
[<table id="browserTable" cellpadding="0" cellspacing="0" margin-left="0" border="1" class="display dataTable" aria-describedby="browserTable_info" role="grid" style="width: 1339px;">…</table>]
But the new does not.
I am at a loss. What am I doing wrong? Can anyone help?
Use a small-case d to create a new DataTable instance:
var tableRef = $("#example").dataTable({
// options
});
Large-case D is used to access the API after datatable is instantiated:
$("#example").DataTable();
equals
$("#example").dataTable().api();
or
tableRef.api();
More information
$(document).ready(function tableload() {
$('table.display').dataTable( {
"sScrollY": "300px",
"sPaginationType": "full_numbers",
"iDisplayLength": -1,
// "aLengthMenu": [[20, 50, 100, -1], [20, 50, 100, "All"]],
"aLengthMenu": [[10, 20, 50, -1], [10, 20, 50, "All"]],
"bScrollCollapse": true,
"bPaginate": true,
"bJQueryUI": true,
"aoColumnDefs": [
{ "aTargets": [ -1 ] }
]
} );
/* Add a click handler to the rows - this could be used as a callback */
$("#example tbody tr").click( function( e ) {
if ( $(this).hasClass('row_selected') ) {
$(this).removeClass('row_selected');
}
else {
oTable.$('tr.row_selected').removeClass('row_selected');
$(this).addClass('row_selected');
}
});
/* Add a click handler for the delete row */
$('#delete').click( function() {
var anSelected = fnGetSelected( oTable );
if ( anSelected.length !== 0 ) {
oTable.fnDeleteRow( anSelected[0] );
}
} );
/* Init the table */
oTable = $('#example').dataTable( );
} );
HTML
<table align="center" width="700" cellspacing="0" border="0" class="display" id="example">
<thead>
<TR>
<TH>column A</TH>
<TH>column B</TH>
<TH>column C</TH>
<TH>column D</TH>
<TH>column E</TH>
</TR>
</thead>
<tfoot>
<TR>
<TD align="center" valign="bottom"> <B> TOTAL</B> </TD>
<TD></TD>
<TD></TD>
<TD></TD>
<TD></TD>
</TR>
</tfoot>
</table>
Many thanks to all those who have offered help.
When creating a jsfiddle to demonstrate the problem, I failed to recreate it. Feeling sheepish, I looked a little deeper, and now feel pretty confident that the problem -- the lost (selector).DataTable() value -- is a consequence of obtaining that value in an async callback, a situation (with remedies) described here.
In my case the async code is a websocket handler: I create the DataTable in response to receiving a matrix from my websocket server. Though the solution is not yet clear to me, I realize now that my question as originally posed failed to describe the actual situation, and was thus misleading.
Thanks to all who offered help!
Paul
Related
Let's say I have a Data Table like so:
<table id="history" class="display">
<thead>
<th>Player</th>
<th>Word</th>
<th>Value</th>
<th>Message</th>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
</tbody>
</table>
I have a function that receives a payload from the server and adds a row to the datatable with the relevant information
var history_data_table = $('#history').DataTable({
"pageLength": 5,
"searching": false,
"bLengthChange": false,
"language": {
"emptyTable": "Words that you discover will appear here."
}
});
function liveRecv(word_payload) {
history_data_table.row.add([word_payload.id_in_group,
word_payload.word,
word_payload.word_value,
word_payload.message]
).draw();
Naturally, this will add the row to the end of a paginated table. This table is a list of transactions in a game, and I want to present the most recent transactions to the user, such that every row that's added is added to the top of the data-table. What is the easiest way to achieve this?
You could try this method using jQuery
$('#history tr:first').after("<tr role="row"><td></td><td>add you own row</td></tr>");
or you could use DataTables inner function to access the array of rows
var history_data_table = $('#history').dataTable();
var DisplayMaster = history_data_table.fnSettings()['aiDisplayMaster'];
var tableapi = history_data_table.api();
var getlastrow = DisplayMaster.pop();
DisplayMaster.unshift(getlastrow);
tableapi.draw(false);
I am trying to display only 3 digits after decimal point but I'm unable to do so. I tried with toFixed() method but I couldn't succeed.
Here's my fiddle.
HTML source code:
<table id="example" class="display" cellspacing="0" width="100%">
<thead>
<tr>
<th>DATE</th>
<th>CODE</th>
<th>PRODUCT</th>
<th>QUANTITY</th>
<th>UNIT</th>
<th>VALUE</th>
<th>COUNTRY</th>
</tr>
</thead>
<tbody>
<tr>
<td>01/01/2017</td>
<td>84571001</td>
<td>MACHININGCENTRESHORIZONTAL</td>
<td>13</td>
<td>NOS</td>
<td>22.1382568</td>
<td>JAPAN</td>
</tr>
<tr>
<td>03/01/2017</td>
<td>84571001</td>
<td>MACHININGCENTRESHORIZONTAL</td>
<td>33</td>
<td>NOS</td>
<td>54.5104524</td>
<td>JAPAN</td>
</tr>
</tbody>
</table>
Can anyone help me out?
The easiest is to use the built-in number helper :
columnDefs: [{
targets: [5],
render: $.fn.dataTable.render.number(',', '.', 3)
}]
Updated fiddle -> http://jsfiddle.net/ebRXw/3627/ Just an example, follow the link for details about all the options you can use along with the number renderer.
you can define a custom renderer for one or multiple columns.
https://datatables.net/examples/advanced_init/column_render.html)
$('#example').DataTable({
responsive: true,
columnDefs: [{
targets: [5],
render(v){
return Number(v).toFixed(3)
}
}]
});
You could transform the cells' values before you apply DataTable.
Here is how you would do it, assuming the cells that need to be modified have the hi class.
$(document).ready(function() {
$('#example .hi').each(function() {
var num = $(this).html(); // get the content of the cell
num = parseFloat(num); // transform it to a JavaScript number
num = num.toFixed(3); // Limit the number of decimals to 3
$(this).html(num); // Update the HTML content
});
$('#example').DataTable({
responsive: true
});
});
I am using angular datatables and I have only one column.
When I bind it, the data comes in an ascneding order, while I want to display it in the order I recived it.
Can someone please help.
Controller :
var vm = this;
vm.dtOptions = DTOptionsBuilder.newOptions()
.withButtons([
'print',
'pdfHtml5',
]);
vm.dtColumnDefs = [
DTColumnDefBuilder.newColumnDef(0).notSortable()
];
HTML :
<div ng-controller="formViewController as frmView">
<table datatable="ng" dt-options="frmView.dtOptions" dt-column-defs="frmView.dtColumnDefs" class="row-border hover">
<thead>
<tr>
<td>
{{Title}}
</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="plugin in newArray track by $index">
<td>
//Content
</td>
</tr>
</tbody>
</table>
</div>
Look at order, formerly known as aaSorting. Add
.withOption('order', [])
to your dtOptions. The default value of order is [[0, 'asc']], setting it to [] will prevent dataTables from making an initial sort on the first column after initialisation.
Resolved
this.dtOptions ={
ajax:{},
columns:[],
order:[] //<= Use this
}
This worked for me. I tried several other ways, but thus seems to be the better solution.
Try This
dtOptions: DataTables.Settings = {};
ngOnInit() {
// table settings
this.dtOptions = {
pagingType: 'full_numbers',
pageLength: 10,
retrieve: true,
order:[[0, 'desc']] // '0' is the table column(1st column) and 'desc' is the sorting order
}
}
So I was able to get part 1 of my question to work, which is located here: Apply column search to current jQuery DataTable
That was utilizing a dropdown select method to the individual columns. However it appears that utilizing an INPUT box would be more effective.
So I came across this fiddle: http://jsfiddle.net/dmurph/b71jtjf1/
This is exactly what I am looking for. So first off, I added to my current table:
<table class="table table-bordered" id="example1" width="100%">
<thead>
<tr>
<th>Edit/Del</th>
<th>Booking</th>
<th>Quote</th>
........
</tr>
</thead>
<thead class="filters">
<tr>
<th>Edit/Del</th>
<th>Booking</th>
<th>Quote</th>
........
</tr>
</thead>
// the DATATABLE IN BETWEEN </thead> and </table>
</table>
Now utilizing the code from the jfiddle link I provided above, this is what I have in total:
$('#example1 .filters th').each(function(){
var title = $('#example1 thead th').eq($(this).index()).text();
$(this).html('<input type="text" placeholder="Search '+title+'" />');
});
My original javascript to print the datatable comes next:
var $dataTable = $('#example1').DataTable({
"ajax": serviceUrl,
"iDisplayLength": 25,
"order": [[ 6, "desc" ]],
"scrollY": 600,
"scrollX": true,
"bDestroy": true,
"columnDefs": [ {
"targets": 0,
"render": function ( data, type, full, meta ) {
return '
<a class="editBookingLink" id="editBookingLink" href="#">Edit</a>
<a class="delBookingLink" id="delBookingLink" href="#">Del</a>';
}
}]
});
So far so good...the datatable still displays. But here comes the part where I'm having the issue:
Immediately after the above code, I have this (according to the jfiddle link):
$dataTable.columns().eq(0).each(function(colIdx){
$('input', $('.filters th')[colIdx]).on('keyup change', function(){
table
.column(colIdx)
.search(this.value)
.draw();
});
});
So errors until I try to search the INPUT field...well first of all, the column search doesn't search anything, but then I check the console and the error I am receiving is "Uncaught ReferenceError: table is not defined" pointing to line 805, which doesn't really make sense, because line 805 is in my original code where it reads below:
"scrollX": true
I am not sure why I am getting this error.
Change table to $dataTable, so it reads:
$dataTable
.column(colIdx)
.search(this.value)
.draw();
Using DataTables 1.9.4 and JQuery 1.4.4.
I'm trying to create a table which filters certain rows based on the visible column. The table is driven by an AngularJS like in-house controller.
When the table is displayed, the filter works fine, but thereafter, if the value changes, the filter is not updated.
The controller consists of an array (one for each row). When the table is updated through it, the filter is not reapplied. How can I make the filter reevaluate each row when the data changes?
HTML as generated by controller:
<table id="table-status">
<thead>
<tr>
<th>visible</th>
<th>Name</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>name1</td>
<td>1</td>
</tr>
<tr>
<td>0</td>
<td>name2</td>
<td>2</td>
</tr>
<tr>
<td>1</td>
<td>name3</td>
<td>3</td>
</tr>
</tbody>
</table>
The DataTables initialization:
var oTable = $("#table-status").dataTable( {
"aoColumnDefs": [ { "bVisible": false, "aTargets": [ 0 ] },
{ "bVisible": true, "aTargets": [ 1 ] },
{ "bVisible": true, "aTargets": [ 2 ] } ],
"bSort": false,
"bFilter": true
} );
oTable.fnFilter("1", 0, false, false, false, false);
I'm not entirely sure if this is what you need, but I rolled my own function to display or not some rows, based on a column called Status.
I have a checkbox that can contain the values 0, 1, 2 and 3.
First, I get the regex function associating the values I want to filter:
var filter = "^" + $("#filterStatusCheck option:selected").map(function() {
return this.value;
}).get().join("|") + "$";
Which returns, for instance, ^1|2$, meaning I want to filter the values 1 and 2.
Then, I search() the DataTable, looking for those elements (not me, actually, but rather their search() method.
var t = s.getTable().DataTable();
t.column(8).search(filter, true, false).draw();
Here, on column with the index of 8, I'm doing so that it searches, using the above filter, and then draw() the DataTable again.
In your case, you might want to figure out what event you can attach the above code (maybe right after the row has been updated?). Your filter would be 1 (visible, right?), whereas your column search would be 0 (the first column called visible).
Hope it helps.