Search code examples
javascriptphphtmlinnerhtmllist.js

How pull innerHTML of element created by javascript function


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?


Solution

  • 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.