Apply column search to current jQuery DataTable part 2 - javascript

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();

Related

Correct way to check if yajra/laravel table was already initialized?

In use laravel 5.7 / jquery 3 / blade app I use yajra/laravel-datatables-oracle 8
and open it in modal dialog and I open this dialog for the 2nd/3rd time
I got warning message :
DataTables warning: table id=get-fee-dt-listing-table - Cannot reinitialise DataTable
In blade file :
<div class="modal-body">
<div class="table-responsive dataTables_header">
<table class="table table-bordered table-striped text-primary" id="get-fee-dt-listing-table">
<thead>
<tr>
<th></th>
and in .js file:
bookingsAndAvailability.prototype.showFeesSelection = function () {
console.log('showFeesSelection::')
$("#div_check_in_fees_modal").modal({
"backdrop": "static",
"keyboard": true,
"show": true
});
// var dtListingTable= document.getElementById('get-fee-dt-listing-table')
// dtListingTable = null // If to uncomment these 2 lines - they do not help
$("#get-fee-dt-listing-table").html('') // // If to uncomment these 2 lines - they do not help
oTable = $('#get-fee-dt-listing-table').DataTable({
processing: true,
language: {
"processing": "Loading fees..."
},
I close the modal with command :
$("#div_check_in_fees_modal").modal('hide');
which is correct way to check if table was already initialised?
Thanks!
You can use $.fn.dataTable.isDataTable() for this.
From the docs:
This method provides the ability to check if a table node is already a
DataTable or not. This can be useful to ensure that you don't
re-initialise a table that is already a DataTable.
Please note that this is a static function and is accessed through the
$.fn.dataTable object, not an API instance. It can be accessed at any
time, even before any DataTables have been created on the page.
if ( ! $.fn.DataTable.isDataTable( '#example' ) ) {
$('#example').dataTable();
}
In your case it would be something like this:
if (! $.fn.DataTable.isDataTable('#get-fee-dt-listing-table')) {
oTable = $('#get-fee-dt-listing-table').DataTable({
processing: true,
language: {
"processing": "Loading fees..."
},
...
}

jQuery Datatables Reload

I'm facing an issue using the Datatables plug-in regarding a table reload after the user adds a row.
I'm receiving some JSON data as part of a webservice call, after successfully receiving that data, I am calling a function that will build the table rows and append them to the tbody of the datatable as follows:
const buildTableRows = obj => {
const table = document.querySelector('#participantes tbody');
table.innerHTML = "";
for (item of obj) {
const tableRow = `<tr id="${item.ContactoId}" data-contributos="${item.Contributos}" data-updated="false" class="participante-row"><td><i class="material-icons">arrow_right</i>${item.Nome}</td><td class="contributos"><input value="${item.Contributos}">&nbsp&nbsp&nbsp<i class="material-icons delete">delete_forever</i></td></tr>`;
table.insertAdjacentHTML('beforeend', tableRow);
}
}
After this, I call another function responsible for initializing the Datatable and saving it to a global object for future reference:
const buildDataTable = () => {
const table = $('#participantes').DataTable({
"pagingType": "simple_numbers",
"pageLength": 4,
"lengthChange": false,
"columnDefs": [{
"targets": 1,
"orderable": false
}],
responsive: true
});
controlObj.datatable = table;
}
In my HTML I have a dynamically generated select element which lets the user add a row to the table. When the user adds the row, those two functions get called again. I can see the new row in my data structure but the table doesn't get refreshed without a page reload. I went through the plugin docs and tried to use the destroy method, rows.add(), clear(), draw() etc.. but nothing seems to work for me. The table structure is already in the DOM, I just need to reload the table. Any help would be much appreciated
Datatable cannot be clear and redraw for updated HTML DOM for table but it has to be inserted using JSON array.
To refresh it after change in DOM, you need to destroy the table and re-initalize it.
See below example where on click of ADD button I have added new row and reiniitalized the table but before that I have destroyed it.
$(document).ready(function() {
//Initialize the table and save it in a variable.
var table = $('#example').DataTable();
var id = 0;
$('#add').on('click', function(){
table.destroy();
//add row to the table
var html = '<tr><td>' + id + '</td><td>First Name' + id + '</td><td>Last Name' + id + '</td></tr>';
//console.log(html);
$('#example tbody').append(html);
id++;
table = $('#example').DataTable();
});
} );
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.20/css/dataTables.jqueryui.min.css">
<script type="text/javascript" language="javascript" src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>
<table id="example" class="display nowrap" style="width:100%">
<thead>
<tr>
<th>ID</th>
<th>First name</th>
<th>Last name</th>
</tr>
</thead>
<tbody>
<tr>
<td>00</td>
<td>First</td>
<td>Last</td>
</tr>
</tbody>
</table>
Click Button to Add row : <input id="add" value=" ADD " type="button">
Yes you can use DataTable api. without destroying table you just need a function.
$(document).ready(function() {
var dt = $('#example').DataTable();
$('#addRow').click(function () {
var rowHtml = $("#newRow").find("tr")[0].outerHTML
console.log(rowHtml);
dt.row.add($(rowHtml)).draw();
});
});
here is working example

$("#example").DataTable() returns empty array

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

Applying fnFilter to a modified table

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.

Specify column data type with a <th> attribute for DataTables

We're using the DataTables jQuery plugin (http://www.datatables.net) to create sortable tables. This plugin auto-detects the data type of the data in each column.
When you want to specify the data type of a column yourself, you add the "aoColumns" attribute when you initialize the datatable:
$('#accountTable').dataTable({
"bPaginate": false,
"sScrollX": "100%",
"bScrollCollapse": true,
"aoColumns": [
null,
null,
{ "sType": "currency" },
{ "sType": "currency" }
]
});
Note, I downloaded the currency data type plugin for datatables. This works great.
However, I'm concerned that if we ever make changes to the table column, we'll forget to go back into the JS and change how the datatables plugin is initialized on that table.
So... It would be ideal to specify the data types directly in the table as necessary:
<table class="dataTables display">
<thead>
<tr>
<th>Category</th>
<th>Product</th>
<th sType="currency">Cost</th>
<th sType="currency">Retail</th>
...
Is there any way to do this, either with default functionality of DataTables (which I can't find) or using a JS loop or something to loop through the tags of the table and update the sType where "sType" attribute exists?
Here is an absolutely cool way to do it:
Your header HTML:
<table id="sorted-table">
<thead>
<tr>
<th data-s-type="string">Number</th>
<th data-s-type="html">Complex Name</th>
<th>Price</th>
<th data-b-sortable="false">Action</th>
</tr>
</thead>
...
Your JS:
$('#sorted-table').dataTable({
...
"aoColumns": $('#sorted-table').find('thead tr th').map(function(){return $(this).data()})
});
Note: those dashes in data attributes are needed. They get converted to camelCase form by jQuery which makes it compatible with the data tables API.
Picking up on CBroe's comment, this is exactly what I do. Just ensure that your custom attributes are prefixed with data-, such as data-stype='currency' per the HTML specs.
Having your JS loop through and check for attributes on the headers would work, but you can't just invent an sType attribute and have it show up in the DOM. You'd have to subvert a valid but unused attribute like headers (and that might cause trouble for screen readers; there may be a better option).
Edit:
OK, having read CBroe's comment, I guess it is possible to give an element an arbitrary attribute.
So, if you wanted to be HTML5 compliant, you could name the property data-sType and then do something like this:
var aoColumns = [];
$('#accountTable > th').each(function() {
var sType = $(this).getAttribute("data-sType");
aoColumns.push(sType ? sType : null);
});
$('#accountTable').dataTable({
...
"aoColumns": aoColumns
});
Thanks to all for your help! I had to make a couple tweaks to Russell Zahniser's comment for it to work for me:
Changed $('#accountTable > th') to $('#accountTable thead th')
Changed aoColumns.push(sType ? sType : null) to aoColumns.push(sType ? { "sType" : "currency" } : null)
End result:
var aoColumns = [];
$('#accountTable thead th').each(function() {
var sType = $(this).getAttribute("data-sType");
aoColumns.push(sType ? { "sType" : "currency" } : null);
});
$('#accountTable').dataTable({
...
"aoColumns": aoColumns
});

Categories

Resources