I m using jquery datatables in many pages and its working good in every page and in a single page its not working properly, i mean when i use tab to go through datatable, it works fine for the first time and when i try to do the same for second time, if i try to focus on any thing in few seconds in data table, the focus disappears and the foucs starts from the starting of the page.
Here goes the code
function tableCall(){
var clientId = $('#clientId').val();
var versionCount = $('#versionCount').val();
var fromDate = $('#fromDate').val();
var toDate = $('#toDate').val();
$.ajax({
url: auditTrail.props.reporttableURL,
type: "POST",
dataType: "json",
data: {
clientId:clientId,
versionCount:versionCount,
fromDate:fromDate,
toDate:toDate
},
success: function (data) {
searchJSON = data.data;
var len=searchJSON.length;
if (len > 0){
$('.no-data, #warning-sign').hide();
createTable();
}else{
$('.no-data').hide();
$('#warning-sign').show();
}
}
});
}
function createTable() {
wwhs.setADAAttrDynamic($('#auditTable'));
if ($.fn.DataTable.isDataTable('#auditTable')) {
// table.destroy();
$("#auditTable tbody").empty();
}
table = $('#auditTable').dataTable({
"searching":false,
"destroy":true,
"autoWidth": false,
"ordering": true,
"destroy":true,
"stateSave": true,
"drawCallback": attachEvents,
"stateLoadParams": function (settings, data) {
return false;
},
data: searchJSON,
columns: [{
data: "reportName"
}, {
data: "reportStatus"
}, {
data: "timeStamp"
}, {
data: "requestedBy"
}],
"columnDefs": [{
"render": function (data, type, row) {
if(row.reportStatus.toUpperCase() == 'PROCESSED')
return '<a class="blue-text" " data-name="'+ row.reportName +'">' + row.reportName + '</a>';
else
return row.reportName;
},
"width": "50%",
"targets": 0
}, {
"width": "15%",
"targets": 1
}, {
"width": "20%",
"targets": 2
}, {
"width": "15%",
"targets": 3
}]
});
}
I think the problem is because the datatable instance is not destroyed.
Since datatables saves all the nodes into an object and renders it when ever it wants, emptying the tbody doesnt do anything. it just removes the elements in the page which can be re-drawn/re-rendered by datatable from its stored object.
You can check if the object is already initialized and the destroy it before re-initializing.
if(typeof table != "undefined")
table.destroy();
So the final code will look something like
function tableCall(){
var clientId = $('#clientId').val();
var versionCount = $('#versionCount').val();
var fromDate = $('#fromDate').val();
var toDate = $('#toDate').val();
$.ajax({
url: auditTrail.props.reporttableURL,
type: "POST",
dataType: "json",
data: {
clientId:clientId,
versionCount:versionCount,
fromDate:fromDate,
toDate:toDate
},
success: function (data) {
searchJSON = data.data;
var len=searchJSON.length;
if (len > 0){
$('.no-data, #warning-sign').hide();
createTable();
} else {
$('.no-data').hide();
$('#warning-sign').show();
}
}
});
}
function createTable() {
wwhs.setADAAttrDynamic($('#auditTable'));
if ($.fn.DataTable.isDataTable('#auditTable')) {
if(typeof table != "undefined")
table.destroy();
}
table = $('#auditTable').dataTable({
"searching":false,
"destroy":true,
"autoWidth": false,
"ordering": true,
"destroy":true,
"stateSave": true,
"drawCallback": attachEvents,
"stateLoadParams": function (settings, data) {
return false;
},
data: searchJSON,
columns: [{
data: "reportName"
}, {
data: "reportStatus"
}, {
data: "timeStamp"
}, {
data: "requestedBy"
}],
"columnDefs": [{
"render": function (data, type, row) {
if(row.reportStatus.toUpperCase() == 'PROCESSED')
return '<a class="blue-text" " data-name="'+ row.reportName +'">' + row.reportName + '</a>';
else
return row.reportName;
},
"width": "50%",
"targets": 0
}, {
"width": "15%",
"targets": 1
}, {
"width": "20%",
"targets": 2
}, {
"width": "15%",
"targets": 3
}]
});
}
Related
I am trying to fetch data from an API of WordPress. Here is my code:
column.data().unique().sort().each(function (d,j) {
var practiceArea = d.practice_area;
var jsonPacticeArea = JSON.stringify(practiceArea);
if (jsonPacticeArea !== undefined) {
var res = $.map(jsonPacticeArea.split("|"), $.trim);
for (var i = 0; i < res.length; i++) {
var str = res[i];
str = str.replace(/"/gi, '').trim();
if (arrayPracticeArea.indexOf(str) === -1) {
arrayPracticeArea.push(str);
}
}
}
});
the "column" is the variable that is getting data through an API, and as far as I do console.log(column. data().unique().sort()), that's returning complete data as you can see in the screenshot:
[![enter image description here][1]][1]
and I want to fetch data is marked in red rectangle and store those values in an array, but as soon as I try to add "each" function to fetch the data and store it in an array (in my case its arrayPracticeArea) its returning undefined values.
Can anyone please help me out? I am just not much experienced with Javascript API.
Here is my AJAX code:
var tableAttorney = $('#table_affliate_attorney').DataTable({
destroy: true,
searching: true,
bLengthChange: false,
scrollX: true,
scrollY: 440,
autoWidth: false,
"language": {
"emptyTable": "We are sorry but there are no Affiliate Attorneys within a 150 mile radius of your requested search"
},
ajax: {
type: 'get',
url: "/wp-admin/admin-ajax.php",
dataType: 'json',
cache: false,
data: {
'action': 'get_attorney_ajax',
'center_lat': center_lat,
'center_long': center_long,
'state': state,
'city': city,
'zip': zip
}
},
columns: [
{"data": "title"},
{"data": "city"},
{"data": "state"},
{"data": "zip"},
{"data": "distance"},
{
"data": "phone",
className: 'datatablePhone',
render: function (data) {
return '' + data + '';
}
},
{
"data": "email",
className: 'px190EM',
render: function (data) {
return '' + data + '';
}
},
{
className: 'js-practice-area',
"data": "practice_area"
},
{
"targets": -1,
"data": 'email',
render: function (data) {
return "<a class='contact-lawyer' href='#' data-toggle='modal' data-target='#exampleModal' data-whatever='#mdo' data-email='"+data+"'>Contact</a>";
}
},
],
columnDefs: [
{"width": "150px", "targets": [0]},
{"width": "130px", "targets": [5]}
],
So I am trying to fetch data from columns->data that has value practice_area.
Here is the fiddle link where I have hosted my whole JS code: https://jsfiddle.net/fareeboy/apor08jn/1/
[1]: https://i.stack.imgur.com/4EOZS.png
I would like to declare my jQuery datatable without initially populating it and later when calling Ajax functions, I would like to take the results and use that as the data source for my data table, right now I am making multiple Ajax calls for the same purpose and I would like to eliminate this if possible.
$.ajax({
type: "GET",
url: "/Receiving/GetUnorderedParts",
datatype: "html",
data: { "id": button.attr("data-ponumber") },
success: function(data) {
var orderButton = $(".js-Order");
orderButton.removeClass("invisible");
tbl = $("#UnorderedDetail")
.DataTable({
"destroy": true,
"searching": false,
"ordering": false,
"lengthChange": false,
"pagingType": "full_numbers",
"paging": true,
"lengthMenu": [10, 25, 50, 75, 100],
ajax: {
url: "/Receiving/GetUnorderedParts",
data: { "id": button.attr("data-ponumber") },
datasrc: ""
},
"columnDefs": [
{
targets: -1,
className: 'dt-body-center'
}
],
columns: [
{
data: "Description"
},
{
data: "VendorPartNumber"
},
{
data: "Quantity"
},
{
data: "CartID",
render: function(data) {
return "<button class='btn btn-danger js-delete' data-cart-id=" +
data +
">Delete</button>";
}
}
] //EOColumns
}); //EODataTable
} //EOSuccess
}); //EOInnerAjax
You can call a function to build the data table on success something like:
$.ajax({
type: "GET",
url: "/Receiving/GetUnorderedParts",
datatype: "html",
data: { "id": button.attr("data-ponumber") },
success: function(data) {
var orderButton = $(".js-Order");
orderButton.removeClass("invisible");
createTable(data);
}
});
and the function can take in the array of objects and create a data table:
function createTable(dataSet)
{
$('#example').DataTable({
data: dataSet,
"aoColumns": [{
"sTitle": "Description",
"mData": "Description"
}, {
"sTitle": "VendorPartNumber",
"mData": "VendorPartNumber"
}, {
"sTitle": "Quantity",
"mData": "Quantity"
}, {
"sTitle": "CartID",
"mData": "CartID",
"mRender": function(data) {
return "<button class='btn btn-danger js-delete' data-cart- id=" + data + ">Delete</button>";
}}]
});
}
Check out a working example . It takes in an array of objects and create a datatable.
Here I have two JS files in which one is main JS file for parent page which contains Datatable which gets populated through ajax call. And other one is specifically for update functionality in which function is defined to update required values into database. That update is done in dialog box. So after successful update sweet alert comes which shows product is successfully updated. So what I want is updated values should be immediately reflected in Datatable of Parent Page. Currently it is showing old value only untill I refresh my page manually. Below are both JS files. And I am new in Javascript and Jquery. So Please help
var oTable;
var url_data_source;
(function(window, undefined) {
window.lastQuery = null;
function initDataSource(after_id) {
url_data_source = '/event/productlocation/ajax?action=data_source';
oTable = $('#datatable').dataTable({
"sAjaxSource": url_data_source,
"bProcessing": true,
"bServerSide": true,
"bFilter": false,
"bRetrieve": true,
"bScrollCollapse": true,
"iCookieDuration": 60*60*24,
"sCookiePrefix": "tkpd_datatable_",
"sPaginationType": "simple",
"scrollX": true,
"aaSorting": [ [0,'desc'] ],
"iDisplayLength": 20,
"aLengthMenu": [[20, 40, 60, 80, 100], [20, 40, 60, 80, 100]],
"oLanguage": {
"sInfoFiltered": "",
"sProcessing": " "
},
"aoColumns": [
{ "sName": "id", "mDataProp": "id"},
{ "sName": "location_id", "mDataProp": "location_id"},
{ "sName": "product_id", "mDataProp": "product_id"},
{ "sName": "status_str", "mDataProp": "status_str"},
{ "sName": "actions", "mDataProp": "actions"},
],
"fnDrawCallback":function(){
},
"initComplete": function(settings, json) {
$("#datatable_paginate").on("click", "#datatable_next", function(){
var after_id = ""
url_data_source = '/event/productlocation/ajax?action=data_source';
after_id_url = $("#after_id_url").val();
after_id = after_id_url.split("after_id=")
url_data_source += "&after_id="+after_id[1];
redraw();
});
},
"fnServerData": function ( sSource, aoData, fnCallback ) {
aoData.push( {"name": "email", "value": $('#search_email').val()} );
if (after_id != "") {
aoData.push( {"name": "after_id", "value": after_id} );
}
if ($('#search_id_product').val()) {
aoData.push( {"name": "product_id", "value": $('#search_id_product').val()} );
}
$.ajax({
"dataType": 'json',
"type": "GET",
"url": url_data_source,
"data": aoData,
"success": function(result) {
var message_error = result.message_error
if (message_error) {
$('#datatable_processing').css("visibility","hidden");
swal({ title: message_error, type: "error"});
} else if (result.status == "OK") {
result.data = formatingDatatable(result.data)
fnCallback(result)
lastQuery = aoData;
} else {
$('#datatable_processing').css("visibility","hidden");
swal({ title: "Tidak ada hasil", type: "info"});
}
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
swal({ title: manager.getAjaxError(XMLHttpRequest), type: "error"});
$('#datatable_processing').css("visibility","hidden");
$('.load__overlay').hide();
},
beforeSend: function() {
$('#datatable_processing').css("visibility","visible");
$('.load__overlay').show();
},
complete: function() {
$('#datatable_processing').css("visibility","hidden");
$('.load__overlay').hide();
}
});
}
});
}
function redraw() {
$("#datatable").dataTable().fnClearTable();
}
function formatingDatatable(events) {
var result = [];
var uri_next;
$.each(events.location_products, function(i, productlocation) {
result.push({
id: productlocation.id,
location_id: productlocation.location_id,
product_id: productlocation.product_id,
status_str: productlocation.status_str,
actions:'<button class="btn btn-primary waves-effect waves-light m-b-5 btn-sm m-r-5 btn-sm detail-productlocation" data-target="#modal-event-productlocation-detail" data-toggle="modal" data-id="' + productlocation.id + '" product-id="' + productlocation.product_id + '" location-id="' + productlocation.location_id + '" status-str="' + productlocation.status_str + '"><i class="glyphicon glyphicon-list"></i> Details</button>'
});
})
$("#after_id_url").val(events.page.uri_next)
uri_next = events.page.uri_next
result.after_id_url = uri_next
return result
}
function initFilter() {
$("#filter-form").submit(function() {
url_data_source = '/event/productlocation/ajax?action=data_source';
if(oTable == null){
initDataSource("");
} else {
oTable.fnDraw();
}
return false;
});
}
$('#datatable_paginate').on('click', '#datatable_next', function() {
initDataSource("");
})
$('#datatable').on('click', '.detail-productlocation', function() {
$('.load__overlay').show();
$("#modal-event-productlocation-detail").remove();
$(this).removeAttr("data-target", "#modal-event-productlocation-detail");
$(this).removeAttr("data-toggle", "modal");
//var id = $(this).attr("data-id");
var dt = {
"id": $(this).attr("data-id"),
"product_id": $(this).attr("product-id"),
"location_id": $(this).attr("location-id"),
"status": $(this).attr("status-str"),
}
$.ajax({
"url": '/event/productlocation/ajax?action=show_dialog_details',
"type": 'GET',
"data": dt,
success: function (result) {
$('.load__overlay').hide();
$("body").append(result);
$(this).attr("data-target", "#modal-event-productlocation-detail");
$(this).attr("data-toggle", "modal");
$('#modal-event-productlocation-detail').modal('show');
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
$('.load__overlay').hide();
swal({ title: manager.getAjaxError(XMLHttpRequest), type: "error", });
},
});
});
$(document).ready(function() {
//initDate();
initFilter();
//initCategoryList();
var after_id = "";
initDataSource(after_id);
});
})(window);
event-productlocation-update.js
function sendProductLocationData() {
var jsonData = {};
var formFields = $(":input");
jQuery.each(formFields, function(i, field) { //Accessing all the element of form and get Key and Value
var key = field.name; //Keyname of each Field
var elementid = field.id; //Id of each Field
elementid = "#" + elementid;
var value = $(elementid).val();
jsonData[key] = parseInt(value);
if (key == "status") {
if ($("#event_checkbox_status").is(':checked') == true) {
jsonData.status = 1;
} else {
jsonData.status = 0;
}
}
});
productlocationdetail = JSON.stringify(jsonData); //Creating json Object
$.ajax({
url: '/update/product/productlocation',
type: 'post',
dataType: 'json',
contentType: 'application/json',
data: productlocationdetail,
"success": function(result) {
var message_error = result.message_error
if (message_error) {
$('#modal-event-productlocation-detail').css("visibility", "hidden")
swal({
title: message_error,
type: "error"
});
$('.modal-backdrop').remove();
} else {
$('#modal-event-productlocation-detail').css("visibility", "hidden")
swal({
title: "Product Location Updated Successfully",
type: "info"
});
$('.modal-backdrop').remove();
}
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
swal({
title: manager.getAjaxError(XMLHttpRequest),
type: "error"
});
$('#modal-event-productlocation-detail').css("visibility", "hidden")
$('.modal-backdrop').remove();
$('.load__overlay').hide();
},
beforeSend: function() {
$('#modal-event-productlocation-detail').css("visibility", "visible")
$('.modal-backdrop').remove();
},
complete: function() {
swal({
title: "Product Location Updated Successfully",
type: "info"
});
$('#modal-event-productlocation-detail').css("visibility", "hidden")
$('.modal-backdrop').remove();
$('.load__overlay').hide();
}
});
}
There are a few way you could handle this.
One way you could handle this is to store the item/s in a variable in a jSON array.
When get confirmation back from the server that that the the update was successful you could then create function to update the dataTable with with this function.
function updateDataTable(dataTableObj,jsonArray)
/*
Clears and populates the dataTable with JSON array
*/
dataTableObj.clear();
jsonArray.forEach(function(row){
dataTableObj.row.add(row);
});
dataTableObj.draw();
}
The other way you could update the table is to create a route on your server that sends the jsonArray but this requires an additional request to the server.
Note: If you use the Ajax call be sure to invoke the function inside the the ajax callback function
How could I perform If else like method in datatable? The variable 'data' returns the value of the variable, which is correct, but if it is blank, it would return the word "from1", "from2" which is supposed to be the value of the variable "from1". Am I doing the right approach or do you have any suggestion as workaround in this problem? thank you for your answers. here is my code:
var table = $('#records').DataTable({
type: 'post',
"ajax": "getHumanTrainings",
"bPaginate": true,
"bProcessing": true,
"pageLength": 10,
"columns": [{
mData: 'tdesc'
}, {
data: "fdDateFrom2",
defaultContent: 'from1'
}, {
data: "fdDateTo2",
defaultContent: 'from2'
}, {
data: "fcTrainor2",
defaultContent: 'train1'
}, {
mData: 'dur'
}]
});
I'd use the render option for the column data that you have, its much more flexible in terms of wanting something to be displayed by default.
var table = $('#records').DataTable({
type: 'post',
"ajax": "getHumanTrainings",
"bPaginate": true,
"bProcessing": true,
"pageLength": 10,
"columns": [{
mData: 'tdesc'
}, {
data: "fdDateFrom2",
render: function(data, type, row) {
// Check if blank
if (data === "") {
return row[<index for from1>]; // Just use the index for from1
}
// If not blank display data normally
return data;
}
}, {
data: "fdDateTo2",
render: function(data, type, row) {
// Check if blank
if (data === "") {
return row[<index for from2>]; // Just use the index for from2
}
// If not blank display data normally
return data;
}
}, {
data: "fcTrainor2",
render: function(data, type, row) {
// Check if blank
if (data === "") {
return row[<index for train1>]; // Just use the index for train1
}
// If not blank display data normally
return data;
}
}, {
mData: 'dur'
}]
});
I've left comments to give you a guide since I'm not familiar with your data, I would suggest printing out your row first over at render so you'd know which index to use.
I have DataTable filled with js-switches, here's the code:
$('#bandsTable').DataTable({
"processing": true,
"serverSide": true,
"ajax": {
'type': 'GET',
'url': 'myUrl',
'data': function (d) {
d._token = Laravel.csrfToken;
}
},
columns: [
{
title: "Number",
data: "number"
},
{
title: "Privileged",
data: "privileged"
}
],
columnDefs: [
{
render: function (data) {
var checked = data ? 'checked' : '';
return '' +
'<input type="checkbox" class="js-switch" id="schedule_deactivation" ' +
checked + ' data-switchery="false" style="display: none;"> \n';
},
targets: 1
}
],
order: [[0, 'asc']],
fnRowCallback: function( nRow, aData, iDisplayIndex ) {
nRow.className = "band-row";
nRow.setAttribute("data-band", aData.number);
return nRow;
},
responsive: true
});
When I filter result's they're displayed correctly, but I don't see checkboxes generated, I can type JS from the console and it works when I type:
var elems = Array.prototype.slice.call(document.querySelectorAll('.js-switch'));
elems.forEach(function (html) {
var switchery = new Switchery(html, {
color: '#26B99A',
secondaryColor: '#ff7a77'
});
});
but I don't know when I should call this code. I have no idea about DataTable lifecycle and where should I inject the code. Should it be some callback defined by DataTables or something else?
please see the documentation on the below link for more, but the code should work as follows:
$('#bandsTable').on('draw.dt', function () {
var elems = Array.prototype.slice.call(document.querySelectorAll('.js-switch'));
elems.forEach(function (html) {
var switchery = new Switchery(html, {
color: '#26B99A',
secondaryColor: '#ff7a77'
});
});
});
Link:
https://datatables.net/reference/event/