Why won't DataTable redraw after manual search - javascript

I have a table which I would like to search manually. After looking at the API, I see that I can just do:
table.search(somestring).draw();
and this should search the table and redraw it, or so I assume.
$(document).ready(function(){
var table = $('table').DataTable({
searching: false,
paging: false,
info: false
});
// add a bunch of rows
for(var i=0; i<20; i++){
table.row.add([
"test "+i, "best "+i, "rest "+i
]);
}
// draw the table
table.draw();
// why won't table redraw with only rows containing 15?
table.search('15').draw();
// this doesn't work either
/*
$('input').on( 'keyup click', function () {
filterColumn( 1 ); // filter only first column
} );
*/
});
function filterColumn ( i ) {
console.log( $('input').val() );
$('table').DataTable().column( i ).search(
$('input').val()
).draw();
}
HTML:
<input>
<table>
<thead>
<tr>
<th>column 1</th>
<th>column 2</th>
<th>column 3</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
Plunker: http://plnkr.co/edit/BlwWWw7mlpde4vKqoX2q?p=preview

You have searching functionality disabled with searching: false, see searching option for more details.
You need to enable searching with searching: true or by removing this option in order for search() method to work.
If you just want to hide filtering control, use dom: 'lrtip', see dom option for more details.

Related

Change datatables ScrollY clicking on button

I have a dataTable like this one:
<table id="example" class="display" cellspacing="0" width="100%">
<thead>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<?php
$query = "SELECT something";
$get_result = sqlsrv_query($conection,$query);
while($row = sqlsrv_fetch_array($get_result)){
$dest = $row['dest'];
$num1 = $row['num1'];
$num2 = $row['num2'];
$num3 = $row['num3'];
echo "<tr>
<td class='hidden'>{$dest}</td>
<td>{$num1}</td>
<td>{$num2}</td>
<td>{$num3}</td>
</tr>";
}
sqlsrv_close($conection);
?>
</tbody>
</table>
<div class="the_button">
View All
</div>
And my js for the dataTable :
$(document).ready(function() {
$('#example').DataTable( {
"scrollY": "100px", // Here
"scrollCollapse": true,
"paging": false,
"ordering": false,
"info": false,
initComplete: function () {
this.api().columns([0]).every( function () {
var column = this;
var select = $('<select><option value="">Select Option</option></select>')
.appendTo( $(column.header()).empty() )
.on( 'change', function () {
var val = $.fn.dataTable.util.escapeRegex(
$(this).val()
);
column
.search( val ? '^'+val+'$' : '', true, false )
.draw();
} );
column.data().unique().sort().each( function ( d, j ) {
select.append( '<option value="'+d+'">'+d+'</option>' )
} );
} );
}
} );
} );
<script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
So lets go in my problem.
I want when the button view all is clicked to change the ScrollY from 100px to auto value or 500px e.g.
I tried many examples found on community but not chance.
I tried by changing the css with js but not luck.
$('.dataTables_scrollBody').css('height', 400); Not working for me this one
Also I tried to leave the ScrollY blank and add the height with CSS and javascript but still no luck.
Any ideas?
Thanks
I have experienced a similar problem, but this was my solution:
$("#myTable").DataTable({scrollY: 100});
// ...
$("#myTable").DataTable({retrieve: true}).destroy();
// ...
$("#myTable").DataTable({scrollY: 200});
I did this because dataTables are intended to run with a single initialisation. The retrieve option on the second executable line above only returns the instance without re-initialisation the dataTable, then I call destroy on it - which reverts all the changes the plugin has made to the DOM. a Simple re-initialisation was the dirty fix that changed the height as per required.

DataTables footerCallback and contenteditable

I have a DataTable that sums over each column using footerCallback. This works perfectly given the data in each column, but I also want to add the ability to change each cell's value that is being summed. I've tried adding "contenteditable" to those cells, but making a change does not affect the sum in the footer.
Here is a simple jsfiddle showing the behavior I'm experiencing: https://jsfiddle.net/rantoun/552y9j90/6/
HTML:
<table id="table1">
<thead>
<tr>
<th>Fruit</th>
<th># Eaten</th>
<th># Remaining</th>
</tr>
</thead>
<tfoot>
<tr>
<th align="right">Count</th>
<th align="left"></th>
<th align="left"></th>
</tr>
</tfoot>
<tbody>
<tr>
<td>Apples</td>
<td contenteditable>3</td>
<td contenteditable>8</td>
</tr>
<tr>
<td>Oranges</td>
<td contenteditable>6</td>
<td contenteditable>5</td>
</tr>
<tr>
<td>Bananas</td>
<td contenteditable>2</td>
<td contenteditable>9</td>
</tr>
</tbody>
</table>
jQuery:
$("#table1").DataTable({
"paging": false,
"searching": false,
"info": false,
"footerCallback": function ( row, data, start, end, display ) {
var columns = [1, 2];
var api = this.api();
_.each(columns, function(idx) {
var total = api
.column(idx)
.data()
.reduce(function (a, b) {
return parseInt(a) + parseInt(b);
}, 0)
$('tr:eq(0) th:eq('+idx+')', api.table().footer()).html(total);
})
}
});
I have also found the DataTables editor (https://editor.datatables.net/examples/inline-editing/simple), which would be perfect for this situation - but it is not open source. Any ideas on how to mimic this inline editing functionality is welcome. I would like to avoid doing this with modals. Any help is appreciated!
Here is an answer that allows you to edit in place with contenteditable.
Note that this requires the dataTables KeyTable plugin
Working Fiddle here
/* Note - requires datatable.keys plugin */
var table = $("#table1").DataTable({
"keys": true,
"paging": false,
"searching": false,
"info": false,
"footerCallback": function ( row, data, start, end, display ) {
var columns = [1, 2];
var api = this.api();
_.each(columns, function(idx) {
var total = api
.column(idx)
.data()
.reduce(function (a, b) {
return parseInt(a) + parseInt(b);
}, 0)
$('tr:eq(0) th:eq('+idx+')', api.table().footer()).html(total);
})
}
});
// keys introduces the key-blur event where we can detect moving off a cell
table
.on( 'key-blur', function ( e, datatable, cell ) {
// The magic part - using the cell object, get the HTML node value,
// put it into the dt cell cache and redraw the table to invoke the
// footer function.
cell.data( $(cell.node()).html() ).draw()
} );
Note - I can foresee that you may get non-numeric data entered. You will have to police that in the key-blur event where you can test the dom node value and act accordingly.

Adding select menu to multiple tables with jquery data tables pluglin

I've got two tables (table1,table2) that are structurally the same, but fed from different sources. Both tables share the class 'display' which I use to initialise the plugin for both tables. This works great for the most part, however the column filters select menu for table2 is duplicated on table1.
I've tried to fix this by using 'this' keyword to indicate a particular instance of the toolbar each of the filters need applying to, but not had much success.
The code that works is:
HTML:
<table id="table1" class="display table-striped table-borded table-hover" cellspacing="0" width="100%">
<thead>
<tr>
<th>Report Name</th>
<th>Year</th>
<th>Montly Snapshot</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Date of Last Refresh --var from warehouse-- </th>
</tr>
</tfoot>
</table>
<table id="table2" class="display table-striped table-borded table-hover" cellspacing="0" width="100%">
<thead>
<tr>
<th>Report Name</th>
<th>Year</th>
<th>Montly Snapshot</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Date of Last Refresh --var from warehouse-- </th>
</tr>
</tfoot>
</table>
JS:
//initialise data tables plugin and apply custom settings.
var reportstable = $('table.display').DataTable({
"sDom": '<"toolbar">Bfrtlp',
"searchCols": [
null, {
'sSearch': 'Current'
}
],
language: {
search: "_INPUT_",
searchPlaceholder: "Search for a Report..."
},
// create select form controls
initComplete: function() {
this.api().columns([1, 2]).every(function() {
var column = this;
var select = $('<select><option value=""></option></select>')
.appendTo($('.toolbar'))
.on('change', function() {
var val = $.fn.dataTable.util.escapeRegex(
$(this).val()
);
column
.search(val ? '^' + val + '$' : '', true, false)
.draw();
});
column.data().unique().sort().each(function(d, j) {
select.append('<option value="' + d + '">' + d + '</option>')
if ($('#info').css('display') == 'block') {
$("#reports_wrapper").css('display', 'none');
}
// add bootstrap classes and placeholder property to form controls to add style
$('.toolbar select').addClass('selectpicker');
$('.dt-button').addClass('btn btn-danger').removeClass('dt-button');
$('.toolbar select').attr('id', 'year');
$('#year').prop('title', 'Financial Year');
$("#year option:contains('Current')").remove();
$('.toolbar select:nth-of-type(2)').attr('id', 'month');
$('#month').prop('title', 'Monthy Snapshot');
$("#month option:contains('undefined')").remove();
});
});
},
// create clear filter button
buttons: [
{
text: 'Clear Filters',
action: function(e, dt, node, config) {
$('select').val('').selectpicker('refresh');
// set Current Year as default filter
reportstable
.search('')
.columns([1]).search('Current')
.columns([2]).search('')
.draw();
}
}
],
//hide specified columns
"columnDefs": [
{
"targets": [1],
"visible": false,
"searchable": true
}, {
"targets": [2],
"visible": false,
"searchable": true
}
]
});
I've updates your jsfiddle and created a new jsfiddle. It's now appending 2 select menus in both tables's wrapper div. I've found why it's appending 4 select menus instead of 2 on the table1's wrapper div. It's because of this code: .appendTo($('.toolbar')). When initComplete callback function is called for table1 there is only one div with class=toolbar, and when the initComplete callback function is called for table2 there is two div with class=toolbar, one in table1's wrapper div and one in table2's wrapper div. that's why on table2's initComplete callback function it append select menus to all divs with class=toolbar. We should rather append to the current table wrapper's div with class=toolbar.

How to use DataTables in case of dynamic rows?

I'm new to the concept of DataTables and I'm referring to this example.
The only difference in my case is that my HTML table is dynamic. HTML code for my table is as follows:
<table id="table_id">
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
</tr>
</thead>
</table>
In my script tag I dynamically add rows to this table using insertRow() method and fetching data from a local json file as follows:
var DemoTable = document.getElementById("table_id");
var DemoRow, DemoCell1, DemoCell2, DemoCell3;
$("#table_id").find("tr:gt(0)").remove(); //to keep the first row headings as set in the html code
for(var i=0; i<DemoData.length; i++) //DemoData contains the fetched json data
{
var DemoRow = DemoTable.insertRow();
DemoCell1 = DemoRow.insertCell(0);
DemoCell2 = DemoRow.insertCell(1);
DemoCell3 = DemoRow.insertCell(2);
DemoCell1.innerHTML = DemoData[i]["Data1"];
DemoCell2.innerHTML = DemoData[i]["Data2"];
DemoCell3.innerHTML = DemoData[i]["Data3"];
}
Also, I've included jquery.dataTables.min.js and dataTables.bootstrap.min.js in the same order.
After this, I've added:
$(document).ready(function() {
$('#table_sub_id').DataTable();
} );
I get the following error:
Uncaught TypeError: Cannot read property 'pageButton' of undefined
Please help. Thanks :)
Instead of this you can use this:
$('#table_id').DataTable( {
"ajax": "data/objects.txt",
"columns": [
{ "data": "cell1" },
{ "data": "cell2" },
{ "data": "cell3" }
]
});

Assign ID to datatable row from json data

i'm new to datatable jquery plugin.
I got stuck with this for more than 2 days. I have a Json Data, i still cant load the table and i also want to assign first column to be id of the row
Here is html:
<table cellpadding="0" cellspacing="0" border="0" class="display"
id="accDetailTable">
<thead>
<tr>
<th>Currency</th>
<th>Current/Savings Account No.</th>
<th>Securities Account No.</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
and my initialization
var oTable=$('#accDetailTable').dataTable( {
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": contextPath + "/user/investorAjax?method=getInvestorAccDetailList",
"iDeferLoading": 57,
} );
Return jsonData from server :
{"sEcho":1,"iColumns":4,"iTotalRecords":16,"iTotalDisplayRecords":16,
"aaData":
[{"DT_RowId":2032,"currency":1,"currentAccNo":"aa","secureAccNo":"aa"},
{"DT_RowId":2033,"currency":1,"currentAccNo":"111","secureAccNo":"111"},
{"DT_RowId":2034,"currency":1,"currentAccNo":"a","secureAccNo":"aa"},
]}
}
But it always hit :
DataTables warning (table id = 'accDetailTable'): Added data (size undefined) does not match known number of columns (3)
Your datatables is waiting for three entries per line and you give it four. In your table declaration (in html part) specify a new header cell <th> at the beginning of your row. You will put ids in it. Then after your dataTables initialization you can hide the first column using fnSetColumnVis(index, visibility) function :
oTable.fnSetColumnVis(0, false); //It will hide your first column
Doing that each row is containing his id (DT_RowId) but not displaying it.
It's kind of easy. Let's just do a tiny change, since you want the first column contains id, you may need to use fnRender, please check the api of datatables, I didn't add this part of code:
var oTable=$('#accDetailTable').dataTable({
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": contextPath + "/user/investorAjax?method=getInvestorAccDetailList",
"aoColumns":[
{"mDataProp":"currency"},
{"mDataProp":"currentAccNo"},
{"mDataProp":"secureAccNo"}
]
});

Categories