Inserting containing DataTable after page load with ajax data value

Inserting containing DataTable after page load with ajax data value

Muddy WatersMuddy Waters Posts: 19Questions: 6Answers: 0
edited July 2019 in Free community support

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

  • kthorngrenkthorngren Posts: 20,255Questions: 26Answers: 4,761

    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

  • Muddy WatersMuddy Waters Posts: 19Questions: 6Answers: 0

    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.

  • kthorngrenkthorngren Posts: 20,255Questions: 26Answers: 4,761

    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

  • Muddy WatersMuddy Waters Posts: 19Questions: 6Answers: 0

    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.

  • kthorngrenkthorngren Posts: 20,255Questions: 26Answers: 4,761

    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

  • Muddy WatersMuddy Waters Posts: 19Questions: 6Answers: 0

    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.

    let slipID; // variable declared outside of document.ready
    
    $(document).ready(function () {
        tblShipped = $('#tblShipped').DataTable({
            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" },
            ],
        });
    }
    
    function displayDiv {  // function declared outside of document.ready
        slipID = rowID;
            $.ajax({
                url: "/api/loadPageContent",
                method: "GET",
                data : {
                    slipID: slipID
                },
    
    }
    
  • kthorngrenkthorngren Posts: 20,255Questions: 26Answers: 4,761
    Answer ✓

    I'm sorry but I'm still not getting the full picture of what you have.

    How do you initialize a table after the page loads?

    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.

    I need an example because I just cant figure it out.

    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 hidden div.
    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

  • Muddy WatersMuddy Waters Posts: 19Questions: 6Answers: 0

    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:

    var loadShippedOrdersTable = function() {
        $('#tblShippedOrdersPackSlipContents').DataTable({
    .....
        });
    };
    
  • kthorngrenkthorngren Posts: 20,255Questions: 26Answers: 4,761

    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

  • colincolin Posts: 15,142Questions: 1Answers: 2,586

    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

This discussion has been closed.