2

Question:

I have a div element with id of "tableholder" which is purely to hold the output on a javascript function that pulls data via ajax from a PHP file.

Within the tableholder element, is a list.js table that works if we simply include he php file instead of calling it via ajax and setting it via innerHTML = "".

How do I use the contents of innerHTML of the tableholder div when it has been created dynamically?

Code so far:

PHP File called:

    <?php

// Connection details for the database being called.
include 'connection.php';

// Putting the query to the database in a variable called "$assets".
$assets = "SELECT * FROM assetregister.getassets";
$assetPull = $conn->query($assets);
$output = "";

// Pulling all of the details from the database and displaying them on the page within the inidividual divs.
if ($assetPull->num_rows > 0) {
    $output .= "<div id='users'>";
    $output .= "<input class='search form-control mt-2' placeholder='Search...' />";
    $output .= "<div class='m-2'>";
    $output .= "<button class='sort btn' data-sort='model'>Sort By Model</button>";
    $output .= "<button class='sort btn ml-2' data-sort='domain'>Sort By Domain</button>";
    $output .= "<button class='sort btn ml-2' data-sort='location'>Sort By Location</button>";
    $output .= "</div>";
    $output .= "<table class='table table.hover list'>";
    $output .= "<thead>";
    $output .= "<th style='text-align: center;'>Model</th>";
    $output .= "<th style='text-align: center;'>Serial Number</th>";
    $output .= "<th style='text-align: center;'>Asset Number</th>";
    $output .= "<th style='text-align: center;'>Domain</th>";
    $output .= "<th style='text-align: center;'>Location</th>";
    $output .= "<th style='text-align: center;'>Type</th>";
    $output .= "</thead>";
    while ($row = $assetPull->fetch_assoc()) {
        $output .= "<tbody class='list' style='text-align: center;'>";
        $output .= "<td class='model'>" . $row['modelName'] . "</td>";
        $output .= "<td class='serialNumber'>" . $row['serialNumber'] . "</td>";
        $output .= "<td class='assetNumber'>" . $row['assetNumber'] . "</td>";
        $output .= "<td class='domain'>" . $row['domain'] . "</td>";
        $output .= "<td class='location'>" . $row['locationName'] . "</td>";
        $output .= "<td class='type'>" . $row['type'] . "</td>";
    }
    $output .= "</tbody>";
    $output .= "</table>";
    $output .= "</div>";
    // If there is no rows in the table that is being called then they will display 0 Results... See below.
} else {
    $output .= "0 results";
}

echo $output;

$conn->close();
?>

This works:

<div class="container-fluid">
    <div class="container">
        <div class="row">
            <main class="col-12" style="margin-top: 80px;">
                <button class="btn btn-primary" onclick="assetSubmit()" style="width: 100%;">Add An Asset</button>
                <?php include 'scripts/getAsset.php'; ?>
            </main>
        </div>
    </div>
</div>
<script>
    populatetable('tableholder');
    window.onload = function () {
        var options = {
            valueNames: ['model', 'serialNumber', 'assetNumber', 'domain', 'location', 'type']
        };
        var userList = new List('users', options);
    };
</script>

This outputs the table and all of the list.js functions work fine as expected.

This Doesn't Work:

<div class="container-fluid">
    <div class="container">
        <div class="row">
            <main class="col-12" style="margin-top: 80px;">
                <button class="btn btn-primary" onclick="assetSubmit()" style="width: 100%;">Add An Asset</button>
                <!-- Pulling in the results of the assets (most recent assets)  -->
                <div id="tableholder"></div>

                <!-- end -->
            </main>
        </div>
    </div>
</div>

<!-- PHP include for the footer -->
<?php include 'assets/layout/footer.php'; ?>

<!-- end -->

<script>
  populatetable('tableholder');
  window.onload = function (){
    var options = {
      valueNames: [ 'model', 'serialNumber', 'assetNumber', 'domain', 'location', 'type']
    };

    var userList = new List('users', options);

  };
function populatetable(name){

  $.ajax({
    url: "scripts/getAssets.php",
    success: function(data){
      document.getElementById(name).innerHTML = data;
    }
  })
}
</script>

What I can assume:

From the various console.log lines and php echos I have put in to test the code, it would appear that the issue it that the javascript command for initiating the list.js table isn't able to find the "user" table that is created by the document.getElementById(name).innerHTML = data; in the populatetable() function. I know this because the folllowing shows blank:

console.log(document.getElementById(tableholder).innerHTML);

What am I doing wrong, or is it not possible to pull the innerHTML data of a dynamically created element?

4
  • What does document.getElementById('tableholder') display when it is logged? Commented Sep 13, 2017 at 10:43
  • I'm investigating this right now, but one thing I found just now: you're opening a new <tbody> in each table row. Commented Sep 13, 2017 at 10:49
  • if I do console.log(document.getElementById('tableholder')); then I can see the entire tableholder element including the innerHTML. However, I can't do the same on a child element of tableholder. Also - I didn't notice the <tbody> thing but it works when directly ported to the page via php so I doubt this is the root cause of the issue. Commented Sep 13, 2017 at 10:49
  • I know what's happening; the ajax call is asynchronous, which means things aren't happening in the order you think they are. Commented Sep 13, 2017 at 10:56

1 Answer 1

1

The problem is that by the time you're calling List(), the ajax call hasn't finished yet, since it's asynchronous.

Try this instead:

var options = {
    valueNames: ['model', 'serialNumber', 'assetNumber', 'domain', 'location', 'type']
};
var userList;

$(document).ready(function() {
    populatetable('#tableholder');
});

function populatetable(id) {
    $.ajax({
        url: "scripts/getAssets.php",
        success: function(data) {
            $(id).html(data);
            userList = new List('users', options);
        }
    });
}

Here I'm using jQuery everywhere it's useful, and I'm calling List() only after the data is actually inserted.

Also note, that like I mentioned in my comment, you need to move the <tbody> line outside the loop.

Sign up to request clarification or add additional context in comments.

2 Comments

I have also moved the <tbody> tag and created a new row for each while loop as you mentioned. The answer works a treat!
Right, you were missing <tr> ... </tr> in both head and body of the table. Glad it's working :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.