Javascript not printing within php loop

Tags: ,



new to php and javascript. I am trying to print an id using javascript within a php loop and nothing is turning up. Here is the code:

$sql = "SELECT dueDate, assignmentName, className FROM assignments INNER JOIN classes ON assignments.class = classes.id ORDER BY DATE(dueDate)";
if ($result = mysqli_query($link, $sql)) {
  if (mysqli_num_rows($result) > 0) {
    echo "Assignments";
    while ($row = mysqli_fetch_array($result)) {
      echo '<div class="popup" id="popup">';
      echo '<div class="overlay"></div>';
      echo '<div class = "content">' . $row['dueDate'] . $row['className'] . '</div>';
      echo '<div class="close-btn content" onclick="togglePopup()">&times;</div>';
      echo '<div class = "btn-group">' . '<button onclick="togglePopup()">' . $row['assignmentName'] . '</button>' . '</div>';
      echo '</div>';
      echo '<script type="text/javascript">  document.write(printID()); </script>';
    }
  }

Answer

The problem is, that you want PHP to know, what printID() is and what it should do. PHP knows nothing about JavaScript functions, because JavaScript and PHP are executed on totally different places. PHP renders your HTML and sends a response to your browser, which executes JavaScript. JavaScript will not be executed, when PHP is processing data.

There ‘s one thing you could do. Wait until everything is rendered and execute your JavaScript functions at the end of your HTML before the </body> tag.

document.addEventListener('DOMContentLoaded', (event) => {
    const elements = document.querySelectorAll('.popup');
    Array.prototype.forEach.call(elements, (element) => {
        let id = printID();
        element.appendChild(document.createTextNode(id));
    });
});

What does the above code snippet? It waits and will be executed, until all DOM is loaded. Then it searches for all elements with the css class named “popup”. By the way there is another issue in your code. You ‘re processing your database query result with a loop and you ‘re using an id attribute. Id attributes should only be used once in your markup. So please use a css class instead of an id attribute. When using a class names “popup” you can read out all elements and execute your javascript function printID() and append a new element. That ‘s it.

Your failure is, that you didn ‘t recognize, that JavaScript is a client side language and is not executed by php. Even when it ‘s written in an html template.

A possible better approach

As you said you want to change a parameter in your togglePopup JavaScript function. The following code shows up a possible solition.

<?php
...
$i = 0;
while ($row = mysqli_fetch_array($result)) {
    echo '<div class="popup">';
    echo '<div class="overlay"></div>';
    echo '<div class = "content">' . $row['dueDate'] . $row['className'] . '</div>';
    echo '<div class="close-btn content">&times;</div>';
    echo '<div class = "btn-group">' . '<button id="popup-' . $i . '">' . $row['assignmentName'] . '</button>' . '</div>';
    echo '</div>';
    $i++;
}

Instead of placing onclick attributes just leave this out. Instead place an id parameter on the button element. Keep in mind, that tha value of a id parameter has to be unique. Instead of using an id attribute, you can use a data attribute like data-id="my-value". Data attributes ensure, that the value of this attribute has not to be unique. Just to show you to possible ways …

At the end of your HTML before the </body> tag place the following.

<script>
    const togglePopup = (event) => {
        let target = event.target;
        let id = target.getAttribute('id');

        // do something with the id attribute
    }
    
    document.addEventListener('DOMContentLoaded', (event) => {
        const elements = document.querySelectorAll('.popup button[id^="popup-"]');
        Array.prototype.forEach.call(elements, (element) => {
            element.addEventListener('click', togglePopup);
        });
    });
</script>

This small snippet adds a click event handler to every button inside an element with the class .popup which has an id attribute which begins with popup-. When this button will be clicked the togglePopup function will be called. Inside this function the id attribute comes from the target element.

With this solution you keep your html markup clean and all javascript stuff is separated from the php code.



Source: stackoverflow