How to empty and refill jquery datatable? - javascript

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>

Related

checkbox click event with jquery datatables not working

I have used jQuery Datatables https://datatables.net/ for my grids.
There are two grids, each has a checkbox in the grid. I need to generate an event when checkbox is checked/unchecked.
I have tried this but it doesn't work. Please let me know what I am doing wrong here..........
$(document).ready(function () {
$('.cBSAGrid tr td').click(function (event) {
alert('0');
});
});
and
$(document).ready(function () {
$('#BSAGrid tr').click(function (event) {
alert('0');
});
});
My datatable jquery
$.ajax({
type: "POST",
url: "/BSA/BSAExceptionGrid",
data: '{ policynumber: "' + txtpolicy.val() + '",clientname:"' + clientname.val() + '" }',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
div.css("display", "none");
$('#BSAGrid').DataTable({
paging: false,
searching: false,
destroy: true,
"bInfo" : false,
data: response,
columns: [
{ "data": "Logged_ID" },
{ "data": "Logged_ID" },
{ "data": "CustomerName" },
{ "data": "ClientType" }
],
aoColumnDefs: [
{
aTargets: [0], // Column number which needs to be modified
mRender: function (o, v) { // o, v contains the object and value for the column
return '<input type="checkbox" id="chkBSA" name="chkBSA" />';
}
//,sClass: 'tableCell' // Optional - class to be applied to this table cell
}
,
{
aTargets: [1],
visible: false
}
],
select: {
style: 'os',
selector: 'td:first-child'
},
order: [[1, 'asc']]
});
},
failure: function (response) {
alert(response);
},
error: function (response) {
alert(response.responseText);
}
});
HTML
<div id="BSAGridContainer" style="display:none;">
<table id="BSAGrid" class="cBSAGrid table table-responsive">
<thead>
<tr>
<th></th>
<th >Logged_ID</th>
<th>Client Name</th>
<th>Client Type</th>
</tr>
</thead>
</table>
</div>
Try bellow code:
$(document).ready(function(){
$(document).on("change", "#chkBSA", function() {
alert('click')
});
});
You could include the onChange event listener in the same column adding this into your column return text onChange="gridCheckboxChange(this);"
If you're using bootstrap 4 custom-checkbox then add a class into your checkbox
.className {left: 0;z-index: 1;width: 1.25rem;height: 1.25rem;}

How to get all checkbox values in cells

I have jQuery datatables with some checkboxes for granting privileges.
I need to get table values to a array. Please enlighten me about how to get checkbox states inside cells, not only the checked ones. Thank you.
My table
<table id="jqueryTable" name="tt" class="table table-striped table-bordered" cellspacing="0">
<thead>
<tr>
<th name="id">
ID
</th>
<th name="name">
PRIV_Name_Str
</th>
<th name="create">
Create
</th>
<th>
Edit
</th>
<th>
View
</th>
</tr>
</thead>
<table>
My datatable query
function LoadProduct(element) {
$.ajax({
url: '/ADM_MAS_Privilege/GetFormData',
data: { YourValue: $('#productCategory').val() },
method: 'post',
dataType: 'json',
success: function (data) {
var table = $('#jqueryTable').dataTable({
paging: true,
sort: true,
searching: true,
scrollY: 200,
data: data,
bDestroy: true,
"columnDefs":
[{
"targets": [2, 3, 4],
"render": function (data, type, row, meta) {
console.log("XX " + meta.row + " " + meta.col);
return type === 'display' ?
'<input type="checkbox" id="p" class="chk" name="group' + meta.row + '" /> ' + data :
data;
columns: [{ "data": "ID", "ID": "ID", "autoWidth": true },
{
"data": "PRIV_Name_Str", "PRIV_Name_Str": "PRIV_Name_Str", "autoWidth": true
},
{
"data": "Create", "Create": "Create", "autoWidth": true
},
{ "data": "Edit", "Edit": "Edit", "autoWidth": true },
{
"data": "View"
}
]
});
}
});
};
My jQuery function to read datatable
$('#upload').click(function () {
var table = document.getElementById("jqueryTable");
var tableArr = [];
for (var i = 1; i < table.rows.length; i++) {
tableArr.push({
ID: table.rows[i].cells[0].innerHTML,
PRIV_Name_Str: table.rows[i].cells[1].innerHTML,
Create: table.rows[i].cells[2].innerHTML,
Edit: table.rows[i].cells[3].innerHTML,
View: table.rows[i].cells[4].innerHTML
});
}
});
I tried table.rows[i].cells[2].innerHTML.getElementById("p").checked even and it's not working.
Since you are using jQuery:
document.getElementById("jqueryTable").each(function (index, element) {
tableArr.push({
ID: element.cells[0].innerHTML,
PRIV_Name_Str: element.cells[1].innerHTML,
Create: element.cells[2].innerHTML,
Edit: element.cells[3].innerHTML,
View: element.cells[4].innerHTML
})
})
You can find the element and the checked property within each cell:
for (var i = 1; i < table.rows.length; i++) {
var cells = table.rows[i].cells;
tableArr.push({
ID: cells[0].innerHTML,
PRIV_Name_Str: cells[1].innerHTML,
Create: cells[2].querySelectorAll('input')[0].checked,
Edit: cells[3].querySelectorAll('input')[0].checked,
View: cells[4].querySelectorAll('input')[0].checked
});
}

Datatable return [Object Object] on index column

I'm using datatable to show data from controller (i'm using Codeigniter) and need to show number column on the left table column.
I have tried:
$(document).ready(function() {
$('#booking_table').dataTable( {
processing: true,
serverSide: true,
language: dt_lang,
pagingType: "simple",
dom: 't<"col-sm-3 text-left"l><"col-sm-3"i><"col-sm-2"r><"col-sm-4 text-right"p>',
autoWidth : true,
ajax: {
"url" : base_url+"book/ajax_history",
"type" : "POST",
data : function (d){
d.show_filter = $('#_show_filter').val();
d.view_type = $('#_view_type').val();
}
},
columns: [
{
data : "b.booking_id",
visible : false,
},
{ data : null}, //where i should put index number
{ data : 'b.booking_date', className : "hidden-xs"},
{ data : 'b.from_name', className : "hidden-xs"},
{ data : 'b.to_name'},
],
responsive: false
});
// reference the table in a variable
var table = $('#booking_table').DataTable();
table.on( 'order.dt search.dt', function () {
table.column(0, {
search:'applied',
order:'applied'
}).nodes().each( function (cell, i) {
cell.innerHTML = i+1;
} );
} ).draw();
My Table:
<table class="table table-condensed" id="booking_table">
<thead>
<tr>
<th class="hidden-xs">id</th>
<th>No</th>
<th class="hidden-xs">
Tanggal
</th>
<th class="hidden-xs">
Pengirim
</th>
<th>
Penerima
</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
Refer to this https://www.datatables.net/examples/api/counter_columns.html
but, it's not working. What am I doing wrong ?
Please try below mentioned solution. Hope this will help you. Actually you initialized datatable two times.
$(document).ready(function() {
var table = $('#booking_table').dataTable({
processing: true,
serverSide: true,
language: dt_lang,
pagingType: "simple",
dom: 't<"col-sm-3 text-left"l><"col-sm-3"i><"col-sm-2"r><"col-sm-4 text-right"p>',
autoWidth: true,
ajax: {
"url": base_url + "book/ajax_history",
"type": "POST",
data: function(d) {
d.show_filter = $('#_show_filter').val();
d.view_type = $('#_view_type').val();
}
},
columns: [{
data: "b.booking_id",
visible: false,
},
{
data: null
}, //where i should put index number
{
data: 'b.booking_date',
className: "hidden-xs"
},
{
data: 'b.from_name',
className: "hidden-xs"
},
{
data: 'b.to_name'
},
],
responsive: false
});
table.on('order.dt search.dt', function() {
table.column(0, {
search: 'applied',
order: 'applied'
}).nodes().each(function(cell, i) {
cell.innerHTML = i + 1;
});
}).draw();
});

jQuery AJAX loading page content

I'm trying to rebuild my site, so that it uses AJAX to load data content inside a div.
This is the function, that handles the loading:
navigate = function(url, title, callback){
//show message to user
toastr.info('<i class="fa fa-spin fa-circle-o-notch"></i> Page is being loaded, please wait.');
//default variables set
title = title || url.substr(url.lastIndexOf('/') + 1).replace(/_/g, ' ').capitalize();
callback = callback || function(){};
//load content to wrapper
$("#content-wrapper").load(url + "?" + $.param({page_load: true}), function(res, status, jqXHR){
toastr.clear(); //hides message
if(status === "error")
{
toastr.error('Page couldn\'t be loaded. Please try again later or contact your system administrator', jqXHR.status + ": " + jqXHR.statusText);
}
else if(status === "success")
{
History.pushState({page: url}, title + " | PCexpres manager", url);
}
//remove modals from inside the content and move them to the end of body - prevents problems with backdrop
$('body > .modal').remove();
$('.modal').each(function(){
$(this).clone(true, true).appendTo("body");
$(this).remove();
})
//execute custom callback
callback(res, status, jqXHR);
})
}
The problem is, that the content, which is being loaded, often (usually) contains more JS (libraries as well as script tags with my code), which is usually not executed correctly. Example of such response:
<script type="text/javascript" src="http://pce.local/assets/js/plugins/datatables/datatables.js?1434971835"></script>
<script type="text/javascript" src="http://pce.local/assets/js/plugins/datatables/extensions/ColReorder/js/dataTables.colReorder.min.js?1434972105"></script>
<link type="text/css" rel="stylesheet" href="http://pce.local/assets/css/plugins/datatables/datatables.css?1434971143" />
<script>
$(function() {
$('.table').dataTable({
dom: 'Rlfrtip',
stateSave: true,
processing: true,
serverSide: true,
searchHighlight: true,
ajax: "http://pce.local/technician/customers/index_processing.json",
columns: [{
data: "checkbox",
name: "return 'id'"
}, {
data: "id",
name: "return 'id'"
}, {
data: "last_name",
name: "return 'last_name'"
}, {
data: "first_name",
name: "return 'first_name'"
}, {
data: null,
render: function(customer) {
return customer.address + (((customer.address_city !== "" || customer.address_zip !== "") && (customer.address !== "")) ? ", " : "") + customer.address_zip + " " + customer.address_city;
},
name: "return 'first_name'"
}, {
data: "email",
name: "return 'email'"
}, {
data: "phone1",
name: "return 'phone1'"
}, {
data: "actions",
name: "return 'id'"
}],
stateSave: true,
order: [
[1, "desc"]
],
aoColumnDefs: [{
'bSortable': false,
'aTargets': [0, -1]
}],
iDisplayLength: 50,
language: {
lengthMenu: "Display <select><option value='25'>25</option><option value='50'>50</option><option value='100'>100</option><option value='200'>200</option><option value='500'>500</option></select> records per page"
}
});
$(".check_all").change(function() {
$(".content_wrapper :checkbox").prop("checked", $(this).is(":checked"))
})
$("#delete_checked").click(function() {
var ids = '';
$(".delete_one:checked").each(function() {
ids += $(this).attr('data-id') + ',';
})
//remove last comma
ids.slice(0, -1)
if (confirm('Are you sure?'))
window.location.href = "http://pce.local/technician/customers/delete/" + ids
})
$(document).on('click', '.delete_customer', function(e) {
e.preventDefault();
$me = $(this);
bootbox.dialog({
title: "Delete customer?",
message: "Are you sure, you want to delete this customer?",
buttons: {
nope: {
label: "No",
className: "btn-default",
callback: function() {
toastr.success('Deletion cancelled');
}
},
yep: {
label: "Yes",
className: "btn-warning",
callback: function() {
window.location.href = $me.attr('href');
}
},
yeah: {
label: "Yes, delete data as well",
className: "btn-danger",
callback: function() {
window.location.href = $me.attr('href') + '/1';
}
}
}
});
})
});
</script>
<div class="content_wrapper">
<a class="btn btn-primary btn-md" href="http://pce.local/technician/customers/add">+</a>
<table class="table table-condensed table-striped table-hover pce-list_table">
<thead>
<th>
<input class="check_all" name="check_all" value="1" type="checkbox" id="form_check_all" />
</th>
<th>ID</th>
<th>Last name</th>
<th>First name</th>
<th>Address</th>
<th>E-mail</th>
<th>Phone</th>
<th>Actions</th>
</thead>
<tfoot>
<th>
<input class="check_all" name="check_all" value="1" type="checkbox" id="form_check_all" />
</th>
<th>ID</th>
<th>Last name</th>
<th>First name</th>
<th>Address</th>
<th>E-mail</th>
<th>Phone</th>
<th>Actions</th>
</tfoot>
<tbody>
</tbody>
</table>
<button id="delete_checked" class="btn btn-primary btn-md" data-nosubmit="data-nosubmit" name="delete_checked">Delete checked</button>
</div>
Is there any proper way to load such content and execute the js as if it was a normal page load?
Here is the correct way to execute javascript after ajax response is added to the container
var arr = document.getElementById('myDiv').getElementsByTagName('script')
for (var n = 0; n < arr.length; n++)
{
eval(arr[n].innerHTML)//run script inside div
}

DataTables hyperlink on all rows in a column

I am using DataTables to generate a table. There is a column containing order numbers.
For example:
...
I need every row in this column to have a hyperlink to view/order?id=? where ? is the contents of row in the Order No column. For example the first row would be a hyperlink to view/order?id=1321755 etc.
What is the simplest way I can do so?
Here is the code that I am using to initialize the DataTables:
<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
$('#example').dataTable( {
"serverSide": true,
"ajax": {
"url": "../server_processing/orders.php",
"type": "POST"
},
"order": [[ 0, "desc" ]]
} );
} );
</script>
<table id="example" class="display" cellspacing="0" width="100%">
<thead>
<tr>
<th>Order No</th>
...
</tr>
</thead>
<tbody>
</tbody>
</table>
Check this out:
http://datatables.net/reference/option/columns.render
You can add a column render callback when you specify columns definition.
var columnsDef = [
...
{
"title": "Order No.",
"render": function (data, type, row, meta) {
return '' + data + '';
}
},
...
];
$("#table").dataTable({
...
"columns": columnsDef,
...
});
The data in that column will be changed to what the render function return.
I needed to use jQuery dataTables and turn a normal field to be a HREF field.
Here you have it all, including also dataTables error handling..
Enjoy..
Yosi Lev
1) The HTML part:
<!-- COMPANIES LIST start -->
<div id="compListDiv" style="visibility:hidden; position : absolute; left : 360px; top : 40px;">
<br>
<table id="compList" align="left" border="1">
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>address</th>
</tr>
</thead>
</table>
</div>
<!-- COMPANIES LIST end -->
2) The javascript dataTables part:
When a button is clicked the following js function is called:
function companiesList(){
accountstable=$('#compList').dataTable({
sort : true,
bFilter: false,
bInfo: false,
paging:false,
autoWidth: true,
ajax: {
url: "http://localhost:8080/j112/rest-1/companies/list",
dataType: 'json',
dataSrc: "data",
error: function ( xhr, textStatus, error ) {
if ( textStatus === 'timeout' ) {
alert( 'Timout error. The server took too long to send back the data.\nPlease try again.' );
}
else {
alert( 'User Not In Session.' );
location.href = "login.html";
}
myDataTable.fnProcessingIndicator( false );
}//function
}/* ajax: */,
scrollCollapse: true,
bDestroy: true,
serverSide:true,
fnRowCallback : function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) { // this function is called for each row, but I could not use it to add the link
// if ( aData[1] == "A" )
//var td0 = $('td:eq(0)', nRow)[0];
// $('td:eq(0)', nRow).html( 'A');
// $('td:eq(0)', nRow).html( '<b>A</b>' )
},// fnRowCallback
initComplete : function(settings, json) { // this function is called after table is populated
//$("#compListDiv").show(); // this did not work so I used regular js to show the DIV
var d1 = document.getElementById('compListDiv');
d1.style.visibility = 'visible';
}, //initComplete
"columnDefs": [
{ "width": "10%", "targets": 0 },
{ "width": "20%", "targets": 0 },
{ "width": "70%", "targets": 0 }
],
"columns":[
//{"data" : "id"},
{ // render
"data": function (data, type, row, meta) {
return '' + data.id + '';
}
},
{"data" : "name"},
{"data" : "address"}
]
}); // dataTable()
}// companiesList()
By Yosi Lev - Feb 22, 2016

Categories

Resources