Cannot destroy() using "Yet Another DataTables Column Filter" plugin - javascript

I'm using DataTables and YADCF to filter a table.
At some point, I need to temporarily unbind both plugins from my table and later bind them again. If I don't use YADCF, I can destroy the datatable and initialise it again. However, when I use YADCF, the filter part of the table isn't destroyed.
HTML:
Create | Destroy
<table id="mytable" class="results table table-striped">
<thead>
<tr>
<th>Head 1</th>
<th>Head 2</th>
<th>Head 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>12</td>
<td>13</td>
<td>14</td>
</tr>
<tr>
<td>12</td>
<td>13</td>
<td>14</td>
</tr>
<tr>
<td>152</td>
<td>13</td>
<td>154</td>
</tr>
<tr>
<td>1762</td>
<td>1873</td>
<td>1874</td>
</tr>
<tr>
<td>124</td>
<td>1343</td>
<td>1124</td>
</tr>
</tbody>
</table>
JS without YADCF JSFIDDLE:
var oTable = $('table');
$('#create').click(function (e) {
e.preventDefault();
oTable.dataTable({
"bJQueryUI": true,
"bStateSave": true,
"bPaginate": false,
"bAutoWidth": false,
});
});
$('#destroy').click(function (e) {
e.preventDefault();
oTable.fnDestroy();
oTable.attr('class', '');
});
JS with YADCF JSFIDDLE:
var oTable = $('table');
$('#create').click(function (e) {
e.preventDefault();
oTable.dataTable({
"bJQueryUI": true,
"bStateSave": true,
"bPaginate": false,
"bAutoWidth": false,
});
// Add YADCF
oTable.yadcf([{
column_number: 1,
filter_type: 'range_number',
ignore_char: 'm'
}, {
column_number: 2,
filter_type: 'text',
filter_default_label: ' '
},
]);
});
$('#destroy').click(function (e) {
e.preventDefault();
oTable.fnDestroy();
oTable.attr('class', '');
});
Can anyone suggest how to destroy the YADCF filter too?

So, this is actually a bug present.
Issue Submitted | Workaround JSFiddle
JS:
var oTable = $('table');
var first = true;
$('#create').click(function (e) {
e.preventDefault();
oTable.dataTable({
"bJQueryUI": true,
"bStateSave": true,
"bPaginate": false,
"bAutoWidth": false
});
if (first) {
first = false;
// Add YADCF
oTable.yadcf([{
column_number: 1,
filter_type: 'range_number',
ignore_char: 'm'
}, {
column_number: 2,
filter_type: 'text',
filter_default_label: ' '
} ]);
} else {
oTable.find('thead').find('[id^=yadcf-filter-wrapper-table]').each(function (i, v) {
var cloned = $(this).clone(true);
console.log( $(this) );
$(this).closest('th').append( cloned );
$(this).remove();
oTable.find('.DataTables_sort_wrapper').css('display', 'inline-block');
});
oTable.find('[id^=yadcf]').show();
}
});
$('#destroy').click(function (e) {
e.preventDefault();
oTable.fnDestroy();
oTable.attr('class', '');
oTable.off();
oTable.find('[id^=yadcf]').hide();
oTable = $('table');
});
$('#add-row').click(function (e) {
e.preventDefault();
$('table').append('<tr><td>' + getRandom() + '</td><td>' + getRandom() + '</td><td>' + getRandom() + '</td></tr>');
});
function getRandom() {
return parseInt(10000 * Math.random(), 10);
}

try the below:
$('#destroy').click(function (e) {
e.preventDefault();
oTable.Destroy();
oTable.attr('class', '');
});

Related

datatable column filtering with serverside(ajax) doesn't work (with django)

I'm developing with django and javascript with datatable.
I want to apply column filtering in my datatable
(https://datatables.net/extensions/fixedheader/examples/options/columnFiltering.html)
but it works fine without serverside option & ajax (in client side),
but it doesn't work with serverside option & ajax.
How can i FIX IT? Please help me..
this is my code.
<table id="sample_table" class="table table-bordered table-hover">
<thead>
<tr>
<th class="sample_id">ID</th>
<th>date</th>
<th>serial</th>
<th>name</th>
<th>birth</th>
</tr>
</thead>
<tbody id="sample_table_body">
</tbody>
<tfoot>
<tr>
<th>ID</th>
<th>date</th>
<th>serial</th>
<th>name</th>
<th>birth</th>
</tr>
</tfoot>
</table>
</div>
<!-- /.card-body -->
</div>
var column_list = [
{ "data" : "id" , "className": "sample_id"},
{ "data" : "receiving_at" },
{ "data" : "serialnumber" },
{ "data" : "name" },
{ "data" : "birthday" },
];
$('#sample_table tfoot th').each(function(){
var title = $("#sample_table thead th").eq( $(this).index() ).text();
$(this).html('<input type="text" placeholder="Search '+title+'" />' );
});
var sample_table = $('#sample_table').DataTable({
"paging": true,
"autoWidth": false,
"lengthChange": false,
"ordering": true,
"processing" : true,
"columns": column_list,
"order": [ [0, 'desc'] ],
"fixedHeader": true,
"orderCellsTop": true,
"ajax": {
url: '/view_datatable/',
type: 'POST'
},
"serverSide" : true, //get data from server
"initComplete": function() { // column filtering RUN after table loaded .
$( '#sample_table tfoot input' ).on( 'keyup change clear', function () {
if ( sample_table.search() !== this.value && this.value.length>0) {
search_result = sample_table.search( this.value );
search_result.draw();
}
} );
}
});
#view.py
def list_datatable(request, companyname):
context = {}
if(request.method == "POST"):
start_page = int(request.POST['start'])
order_direction = request.POST["order[0][dir]"] # direction of ordering(asc, desc)
order_col_no = request.POST["order[0][column]"] # number of index to sort
order_col_name = request.POST['columns[' + str(order_col_no) + '][data]'].strip() # name of colum of ordering
sample_list_all = Sample.objects.all().order_by(order_col_name)
sample_list_per_page = []
for idx, obj in enumerate(sample_list_all[start_page:start_page + 10]):
data = {}
data['id'] = obj.id
data['receiving_at'] = str(obj.receiving_at)
data['birthday'] = obj.birthday
data['serialnumber'] = obj.serialnumber
data['name'] = obj.name
sample_list_per_page.append(data)
#-- end of --#
datalist_to_json = json.dumps(
{"data": sample_list_per_page, "recordsFiltered": len(sample_list_all), "recordsTotal": len(sample_list_all)}
)
return HttpResponse(datalist_to_json, content_type="application/json")

php product comparison table

I'm working on a product comparison table. I want to add a td in every last child in all tr. I want to display all products in vertical in a table. The product comparison table is made using php.
This is the code:
<thead id="table_row">
<tr id="h_td">
<th></th>
<th>product 2</th>
<th>product 3</th>
<th>product 2</th>
<th>add</th>
</tr>
</thead>
<tbody id="pro_table">
<tr class="visible-xs " aria-hidden="true" id="collapse" >
<td colspan="5" >Fature 1</td>
</tr>
<tr id="h_td">
<td>Fature 1</td>
</tr>
<tr class="visible-xs" aria-hidden="true" id="collapse">
<td colspan="5">Fature 2</td>
</tr>
<tr id="h_td">
<td>Fature 2</td>
</tr>
<tr class="visible-xs" aria-hidden="true" id="collapse">
<td colspan="5">Fature 3</td>
</tr>
<tr id="h_td">
<td>Fature 3</td>
</tr>
<tr class="visible-xs" aria-hidden="true" id="collapse">
<td colspan="5">Fature 4</td>
</tr>
<tr id="h_td">
<td>Fature 4</td>
</tr>
</tbody>
<?php
$con = mysqli_connect("localhost","root","","COMPARES");
$b_title = array();
$sql="SELECT * from brands";
$run=mysqli_query($con,$sql);
$num_row=mysqli_num_rows($run);
while($row=mysqli_fetch_assoc($run)){
$rows[] = $row;
foreach($rows as $row){
$b_title =$row['brand_id'];
$b_title =$row['brand_title'];
$data =' '.$b_title.' ';
}
}
?>
<script type="text/javascript">
var tables = document.getElementsByTagName('tbody');
var table = tables[tables.length - 1];
var rows = table.rows;
for(var i = 0, td; i < rows.length; i++ ){
td = document.createElement('td');
td.appendChild(document.createTextNode("<?php echo data ?>"));
rows[i].insertBefore(td, rows[i].lastChild);
}
</script>
This is the result:
Why write you own table when much better options out there already exist?
Using jQuery # http://jquery.com/ and DataTables # https://datatables.net/, you can easily have dynamic column adding capability -- Check out this fiddle for an example: http://jsfiddle.net/4nil/zq7j97c4/10/--
var data_table, row_num, col_num, row_cell, col_cell, iter=0;
var cols = [
{ "mDataProp": "Field1"},
{ "mDataProp": "Field2" },
{ "mDataProp": "Field3" },
{ "mDataProp": "Field4" }
];
var colDef = [{aTargets: [0], sTitle: "Date"},
{aTargets: [1], sTitle: "Number"},
{aTargets: [2], sTitle: "FName"},
{aTargets: [3], sTitle: "LName"},
];
//Get stored data from HTML table element
var results = [{
Field1: "2011/04/23",
Field2: 8,
Field3: "Adam",
Field4: "Den"},
{
Field1: "2011/03/25",
Field2: 6,
Field3: "Honey",
Field4: "Singh"}
];
function initDT(){
//Construct the measurement table
data_table = $('#example').dataTable({
"bJQueryUI": true,
//"sPaginationType": "full_numbers",
//"bProcessing": true,
"bDeferRender": true,
"bInfo" : false,
"bDestroy" : true,
"bFilter" : false,
"bPagination" : false,
"aaData": results,
"aoColumns": cols,
"aoColumnDefs": colDef
});
attachTableClickEventHandlers();
}
initDT();
function attachTableClickEventHandlers(){
//row/column indexing is zero based
$("#example thead tr th").click(function() {    
col_num = parseInt( $(this).index() );
console.log("column_num ="+ col_num );  
});
$("#example tbody tr td").click(function() {    
col_cell = parseInt( $(this).index() );
row_cell = parseInt( $(this).parent().index() );   
console.log("Row_num =" + row_cell + "  ,  column_num ="+ col_cell );
});
};
$("#btnAddRow").click(function(){
//adding/removing row from datatable datasource
var record = {
"Field1": "2011/04/23",
"Field2": '8',
"Field3": "tom",
"Field4": "jerry"};
data_table.fnDestroy();
results.push(record);
//results.pop();
initDT();
$('#example').dataTable().makeEditable({
sUpdateURL: function(value, settings) {
console.log(value);
}});
});
$('#btnAddCol').click(function () {
var oSettings = data_table.fnSettings();
$("#example thead tr th").eq(col_num).after('<th></th>');
cols.push( {"mDataProp": "Field5"} );
colDef.push({aTargets: [4], sTitle: "Message"});
results[0].Field5 = "Msg1";
results[1].Field5 = "Msg2";
data_table.fnDestroy();
data_table.oApi._fnAddColumn(oSettings,null);
initDT();
});
EDIT:
If your content is going to be static, there are plenty of "comparison table" examples, using Bootstrap found here: https://bootsnipp.com/tags/table

How to empty and refill jquery datatable?

I have a jquery datatable on my page. This datatable is gonna show data based on a request made to my api
The HTML that I have is like the following:
<table id="details" class="table table-bordered table-hover table-striped nowrap hidden display" cellspacing="0" width="100%">
<thead>
<tr>
<th> </th>
<th>Patient Full Name</th>
<th class="hidden">LF</th>
</tr>
</thead>
<tfoot>
<tr>
<th> </th>
<th>Patient Full Name</th>
<th class="hidden">LF</th>
</tr>
</tfoot>
<tbody>
<tr id="dummytr2"><td style="text-align:center;padding-top:20px;" colspan="7"><p><em>No Data Available</em></p></td></tr>
</tbody>
</table>
The first <th> is gonna be used to collapse the tr and get the facility (the third <th> or the hidden one) of this patient.
I have a dummy <tr> in the table because I don't want to initialize the datatable at the beginning so I don't get the error message that tells me that I can't initialize my datatable twice.
The request to my api is gonna be triggered through a bunch of buttons like the following:
$.ajax({
url: "https://" + window.myLocalVar + "/api/metrics/GetDetails?metricName=" + metric,
type: "GET",
dataType: 'json',
contentType: 'application/json',
success: function (requests) {
if (requests.length > 0) {
$("#dummytr2").remove();
for (var i = 0; i < requests.length; i++) {
var patient_name = requests[i].PatientFullName;
var lab_facility = requests[i].LabFacility;
tr = '<tr>\
<td class=" details-control"></td>\
<td>' + patient_name + '</td>\
<td class="hidden">' + lab_facility + '</td>\
</tr>';
$("#details > tbody").append(tr);
//click event for each tr
$('#details tbody').on('click', 'td.details-control', function () {
var tr = $(this).closest('tr');
var row = table.row(tr);
if (row.child.isShown()) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
} else {
// Open this row
row.child(format(row.data())).show();
tr.addClass('shown');
}
});
}
}
// NOT SURE WHY IT IS NOT WORKING
$('#details').dataTable().fnDestroy();
var table = $('#details').DataTable({
"scrollX": true,
stateSave: true,
"columns": [
{
"className": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{ "data": "PatientFullName" },
{ "data": "LabFacility" }
],
"order": [[1, 'asc']]
});
},
error: function (err) {
if (err) {
console.log(err);
}
}
});
});
function format(d) {
// `d` is the original data object for the row
var lf = d.LabFacility;
if (lf == "") {
lf = "No Lab Facility"
}
// wrapping text is not working???
return '<div class="table-responsive"><table class="table display" cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">' +
'<tr>' +
'<td>Lab Facility:</td>' +
'<td>' + lf + '</td>' +
'</tr>' +
'</table></div>';
}
This ajax request is gonna get called each time a button is clicked. This means the content of my datatable is going to change each time a button was clicked. I tried to clear and refill it did not work.. I tried to destroy it .. it did not work.. each time I destroy my datatable and execute the script it won't change the content of the table.
I am not sure what's wrong with my code. My code works only for the first time.. the second time you click a button, it won't update my datatable.
Thanks!
You need to:
empty the table with empty()
remove $('#details').dataTable().fnDestroy();
add destroy: true option
For example:
if (requests.length > 0) {
// Empty table
$('#details').empty();
// ... skipped ...
var table = $('#details').DataTable({
destroy: true,
// ... skipped ...
});
// ... skipped ...
}
Please see sample of what I was saying in comments above:
var dataTable_ = null;
var init_ = false;
var initDataTable = function() {
dataTable_ = $('#table').DataTable({
preDrawCallback: function(settings) {
},
drawCallback: function(settings) {
if (init_ === false) {
init_ = true;
}
},
searching: true,
data: [],
fnCreatedRow: function(nRow, aData, iDataIndex) {
},
scrollY: true,
scrollX: true,
responsive: false,
serverSide: false,
autoWidth: false,
processing: false,
scrollCollapse: false,
lengthChange: false,
fixedColumns: false,
info: false,
select: {
info: false,
items: 'rows'
},
dom: '<"toolbar">Bfrtip',
orderMulti: false,
stripeClasses: ['dt-stripe-1', 'dt-stripe-2'],
columns: [{
name: 'test1',
data: 'test1',
title: 'Test1',
type: 'string',
orderable: true
},
{
name: 'test2',
data: 'test2',
title: 'Test2',
type: 'string',
orderable: true
},
]
});
};
var ajaxFunction = function() {
$.ajax({
url: "https://api.myjson.com/bins/7ed89",
type: "GET",
dataType: 'json',
contentType: 'application/json',
success: function(data) {
if (init_ === false) {
initDataTable();
}
if (typeof dataTable_ == 'object') {
dataTable_.rows().remove().draw();
dataTable_.rows.add(data);
dataTable_.draw();
}
//console.log(data);
}
});
};
$('#button').click(function() {
ajaxFunction();
});
<link href="https://cdn.datatables.net/1.10.15/css/jquery.dataTables.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.15/js/jquery.dataTables.min.js"></script>
<table id="table" class="cell-border hover call-list">
</table>
<button id="button">Click To Load Data</button>

jQuery datatables TypeError: b is null

I am facing with a error fired by Firebug when using a jquery datatables plugin
The table is like this:
<table id="dt_cursuri" class="table table-striped table-bordered dTableR">
<thead>
<tr>
<th data-class="expand">Curs</th>
<th data-hide="phone,tablet" data-name="Assign">Domeniu</th>
<th>Tip</th>
<th>Data modif</th>
<th class="centered-cell">Actiuni</th>
</tr>
</thead>
<tbody>
<tr>
<td class="dataTables_empty" colspan="6">Fetching data from server</td>
</tr>
</tbody>
</table>
The datatables initialization:
var oTable;
var responsiveHelper = undefined;
var breakpointDefinition = {
tablet: 1024,
phone : 480
};
var oTable = $('#dt_cursuri');
oTable = $('#dt_cursuri').dataTable( {
"bProcessing": true,
"bServerSide": true,
"sPaginationType": "bootstrap",
"sDom": "<'row'<'col-md-6'l><'col-md-6'f>r>t<'row'<'col-md-6'i><'col-md-6'p>>",
"sAjaxSource": "view/cursuri/server_side.php",
autoWidth : false,
"fnPreDrawCallback": function () {
// Initialize the responsive datatables helper once.
if (!responsiveHelper) {
responsiveHelper = new ResponsiveDatatablesHelper(oTable, breakpointDefinition);
}
},
"fnDrawCallback" : function (oSettings) {
responsiveHelper.respond();
},
"fnRowCallback": function( nRow, aData ) {
responsiveHelper.createExpandIcon(nRow);
},
"aoColumns": [
//{ "sClass": "center", "bSortable": false, sWidth: '2%', "bVisible": false },
{ sWidth: '35%' },
{ sWidth: '25%' },
{ sWidth: '20%' },
{ sWidth: '10%' },
{ "sClass": "center", sWidth: '10%', "bSortable": false }
],
"aaSorting": [[2, 'asc']]
} );
The server side json file is working corectly. The same code is used in other tables that work perfect, but this one is not
Could someone help me?
The error is fired for this line from jquery.datatables.js:
!a.sLoadingRecords && (c && 'Loading...' === b.sLoadingRecords) && D(a, a, 'sZeroRecords', 'sLoadingRecords');
I will answer this question on my own thanks to developers of jQuery Datatables.
The problem was in the server side processing. When using diacritics the datatable is messing with the data so you have to actually control the diacritics with utf8_encode() php function

Datatables is not initializing columnFilter plugin

I already have a table
<table id="currencies-table" class="table table-striped table-bordered table-hover form-data-table">
<thead>
<tr>
<th style="width: 10px;"><input type="checkbox" class="group-checkable" data-set=".form-data-table .checkboxes" /></th>
<th><spring:message code="label.name_pl"/></th>
<th><spring:message code="label.name_en"/></th>
<th><spring:message code="label.name_de"/></th>
<th><spring:message code="label.code"/></th>
<th><spring:message code="label.symbol" /></th>
<th class="num-html-sort"><spring:message code="label.order" /></th>
<th></th>
</tr>
</thead>
<tbody>
<c:forEach var="currency" items="${model.currencies}">
<tr class="odd gradeX">
<td><sf:checkbox path="ids" class="checkboxes" value="${currency.id}"/></td>
<td>${currency.name.pl}</td>
<td>${currency.name.en}</td>
<td>${currency.name.de}</td>
<td>${currency.code}</td>
<td>${currency.symbol}</td>
<td class="center">
<span class="move-arrow move-arrow-down" style="cursor:pointer"><i class="icon-arrow-down"></i></span>
<span class="priority-order badge badge-inverse">${currency.priority}</span>
<span class="move-arrow move-arrow-up" style="cursor:pointer"><i class="icon-arrow-up"></i></span>
</td>
<td><spring:message code="label.details"/></td>
</tr>
</c:forEach>
</tbody>
<tfoot>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</tfoot>
</table>
This is the script that initializes this table.
var defaultSettings = function() {
return {
"bStateSave": true,
"bFilter": true,
"aLengthMenu": [
[5, 15, 20, -1],
[5, 15, 20, Labels.getLabel('label.all')] // change per page values here
],
"iDisplayLength": 15,
"sDom": "<'row-fluid'<'span6'l><'span6'f>r>t<'row-fluid'<'span6'i><'span6'p>>",
"sPaginationType": "bootstrap",
"oLanguage": {
"sUrl": CommonsValues.datatable_lang_path()
},
"aoColumnDefs": [{
'bSortable': false,
'bSearchable': false,
'aTargets': [0, 'no-sort']
},
{
'bSortable': true,
'aTargets': ['date-sort'],
'sType': "date-pl"
},
{
'bSortable': true,
'aTargets': ['datetime-sort'],
'sType': "date-euro"
},
{
'sWidth': "100px",
'aTargets': ['size100']
},
{
'bSortable': true,
'aTargets': ['numeric-sort'],
'sType': "numeric"
},
{
'bSortable': true,
'aTargets': ['num-html-sort'],
'sType': 'num-html'
},
{
'bSortable': true,
'bSearchable': true,
'aTargets': ['rfq-sort'],
'sType': "rfq",
'mData': function(source, type, val) {
if (type === 'set') {
source.value = val;
source.value_display = val;
source.value_filter = val === "" ? "" : $.fn.dataTableExt.ofnSearch['rfq'](val);
return;
}
else if (type === 'display') {
return source.value_display;
}
else if (type === 'filter') {
return source.value_filter;
}
// 'sort', 'type' and undefined all just use the integer
return source.value;
}
},
{
'bSortable': true,
'aTargets': ['offer-sort'],
'sType': 'offer'
},
{
'bSortable': true,
'aTargets': ['price-sort'],
'sType': 'price'
}
],
"fnDrawCallback": function(oSettings) {
$('.group-checkable', oSettings.nTableWrapper).on('change', function() {
var checked = $(this).is(":checked");
$(oSettings.oInstance.fnGetNodes()).each(function() {
if (checked) {
$(this).find('.checkboxes').attr("checked", true);
} else {
$(this).find('.checkboxes').attr("checked", false);
}
$.uniform.update($(this).find('.checkboxes'));
});
}
);
}
};
};
var settings = new defaultSettings();
if ($(this).hasClass('expand-table')) {
settings.sScrollX = "125%";
}
var dataTable = $(this).dataTable(settings).columnFilter({
"sPlaceHolder": "head:after",
"aoColumns": [
null,
null,
{type: "checkbox"},
{type: "checkbox"},
{type: "checkbox"},
null,
null,
null
]
});
After initialization the table doesn't have the input for filtering columns even though other features works (sorting, main filtering, paging).
The table elements (thead,tbody,tfoot) are swapped in the resulting html code.
From what I can see from the provided example code I would say that you forgot to configure the values for the checkbox filters.
The followering should work:
var dataTable = $(this).dataTable(settings).columnFilter({
"sPlaceHolder": "head:after",
"aoColumns": [
null,
null,
{type: "checkbox", values: [ 'value used for filtering', 'displayed label text for checkbox']},
{type: "checkbox", values: ['bemol', 'user']},
{type: "checkbox", values: ['pl','Polish']},
null,
null,
null
]
});
Also try checking this example out:
Checkbox example

Categories

Resources