Inserting containing DataTable after page load with ajax data value
Inserting containing DataTable after page load with ajax data value
I am stuck trying to insert a div into my page that contains a DataTable table element.
On page load, there is a search input and a DataTable containing empty rows. This table will display order details and the search input loads this table. When I input an order ID into the search and it matches, the DataTable loads records based on that ajax call. Because this table is initialized with document.ready on page load, I have no problem just calling ajax.reload() anytime I enter a new order search.
The first column contains a button that when clicked, inserts a div after the orders DataTable that contains the order contents. Clicking the button should call a function and send it the row ID value. This all works. But the table never is displayed because I'm guessing that the table doesn't exist when the page is loaded and the document is ready. I get a valid JSON response from my server containing the right data, and it even reaches the success portion of the ajax call. But no table gets displayed.
I've tried all day to get this working, but I just can't seem to figure it out. I have no problem implementing DataTables when they are displayed on page load, but I really need my project to be able to load divs at will containing DataTables with new values.
Thanks in advance for any help that is offered.
A quick example of my code:
let slipID;
let tblRelatedSlips;
let tblShippedOrdersPackSlipContents;
$(document).ready(function () {
// SHIPPING ORDERS RELATED SLIPS
tblRelatedSlips = $('#tblShipRelatedSlips').DataTable({
order: [[0, "desc"]],
dom: tableOnlyDom,
ajax: {
url: "/api/getShipRelatedItems",
method: "GET",
data: function (data) {
data.orderID = $('#orderID').val();
},
dataSrc: ""
},
columns: [
{ title: "Details", data: "details",
render: function(data) {
js = "displayShipOrdersPackageContents('" + data + "');";
data = '<button class="ui labeled button" id="btnShowSlipContents" data-id="' + data + '" onclick="' + js + '"><i class="box icon"></i>Packing Slip Details</button>';
return data;
}
},
{ title: "Pack Date", data: "packDate" },
{ title: "Carrier", data: "carrier" },
{ title: "Tracking", data: "tracking",
render: function(data, type, row) {
link = row['trackLink'];
link = link.replace("TRACKINGNO", data);
data = '<a href="' + link + '">' + data + '</a>';
return data;
}
},
{ title: "Comments", data: "comments" },
{ title: "", data: "details",
render: function(data) {
js = "deleteRelatedSlips('" + data + "');";
data = '<button class="ui labeled button" type="button" id="btnDeleteRelatedSlip" onclick="' + js + '"><i class="trash icon"></i>Remove</button>';
return data;
}
}
],
columnDefs : [
{targets: 1, type: "date"},
{targets: 5, orderable: false},
],
});
tblShippedOrdersPackSlipContents = $('#tblShippedOrdersPackSlipContents').DataTable({
order: [[0, "asc"]],
pageLength: 25,
initComplete: function(){
console.log('hi');
},
ajax: {
url: "/api/getOrderPackSlipContents",
method: "GET",
data: function (data) {
data.slipID = slipID;
},
dataSrc: "",
},
columns: [
{ title: "Serial Number", data: "serialNum" },
{ title: "Product Name", data: "productName" },
{ title: "Manufacturer", data: "manufacturer" },
{ title: "Manufacture Date", data: "mfgDate" },
{ title: "Value", data: "productValue", className: "currency", render: $.fn.dataTable.render.number(',', '.', 2, '$') },
{ title: "", data: "serialID",
render: function(data) {
js = "deletePackageContents('" + data + "');";
data = '<button class="ui labeled button" type="button" id="btnDeletePackageContents" onclick="' + js + '"><i class="trash icon"></i>Remove</button>';
return data;
}
}
],
});
}
function displayShipOrdersPackageContents(rowID)
{
slipID = rowID;
orderID = $('#lblPdbOrderNum').text();
$.ajax({
url: "/api/loadPageContent",
method: "GET",
data : {
orderID: orderID,
slipID: slipID
},
success: function (res) {
$('#segShippedOrdersPackingSlips').after(res);
tblShippedOrdersPackSlipContents.ajax.reload();
},
error: function (xhr) {
console.log("readyState: " + xhr.readyState + "\nstatus: " + xhr.status);
},
});
This question has an accepted answers - jump to answer
Answers
The place to start is to follow the steps provided at the link in the Invalid JSON Response alert:
https://datatables.net/manual/tech-notes/1
Find out what the response from the server is. This will help determine where to start troubleshooting in your server script.
Kevin
I should have mentioned the JSON response is valid. The table loads without issue if I display the segment on page load.
I believe the issue is related to the table not existing when document.ready is run.
You've posted a lot of code to look through. Without seeing the problem its hard to understand what is going and say exactly what the issue is. Please post a link to your page or a test case replicating the issue.
https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case
Kevin
Sorry, first post and was just trying to be thorough. The code I posted contains two tables declared before document.ready, initialized from document.ready on page load, but only the first table is displayed in the HTML on page load. Then a button click calls a function that displays the segment and refresh/display the table with the new ajax data value.
I will toy with it more today and try to get a better example, and/or a URL that somebody can look at, but I think it's a matter of when the table is initialized that I'm not able to figure out at the moment.
This image shows the form on page load by itself. The slipID value is empty so the table is empty, but table was initialized on page load.
This image shows the form loaded from the button click in first table, after page load.
When you click the button is that when you get the Invalid JSON Response error?
Maybe you can post the JSON response you get after clicking the button.
Take a look at the browser's console for errors after clicking the button.
Kevin
I do not get an invalid JSON response. That portion all works.
I apologize for all the excess words. This really should be a simple question.
How do you initialize a table after the page loads? I need an example because I just cant figure it out.
Below is the rough outline of how I am attempting to do this.
Declare a variable, call a function that sets the variable and loads the div. The loaded div should contain the #tblShipped.
I'm sorry but I'm still not getting the full picture of what you have.
Is the
div
being created when clicking the first table button? Or is it hidden?You can place the Datatable init where you would like.
Here is an example of loading Datatables in tabs and using
columns.adjust()
to adjust column widths when the tab is shown. Maybe you can use a similar concept with a hiddendiv
.https://datatables.net/examples/api/tabs_and_scrolling.html
Can you build a simple example so we can help debug? I would say the ajax portion would not be needed. however if it is you can use one of the ajax templates here:
https://datatables.net/manual/tech-notes/9
Kevin
Thank you for your help Kevin, I really do appreciate it.
I seem to have gotten it to work by just placing the initialization inside a function outside of document.ready
I was under the impression DataTables would only work if initialized inside a document.ready function.
My solution looks like this:
If you call the function a second time you might get the
Warning: Cannot reinitialise DataTable
alert. If you do then follow the steps provided in the link:https://datatables.net/manual/tech-notes/3
Kevin
Hi @Muddy Waters
I may be misunderstanding the problem, but can't you have a div that contains the element and have that hidden until the button press. Once the press happens, you show that div and only then initialise the table. Something like this.
Would that work?
Cheers,
Colin