0

I posted this earlier but it incorrectly got marked as a duplicate of Can scripts be inserted with innerHTML?, which isn't my problem. I'm not trying to run any JavaScript through using innerHTML, I'm trying to run JavaScript that is located in a PHP file called through Ajax/XmlHttp. I am using innerHTML in that JS, but I'm not writing more JS within that. So it's not a duplicate of that question and I'm trying it again now.

Not sure what's going on here. I'll explain the organization of my files first and then get into the code.

The application- Allows the user to select different attributes (i.e. year or name) and view pictures of matching results from a database.

Files- I have a gallery.php file that has a series of HTML form elements acting as selectors to get filtered results from a database. Whenever a selector is set or changed, the file sends a new request to a get.php file that uses Ajax to refresh the results without loading a new page. All that works great. My next task is to implement a modal section where I can click on an image and view a bigger version which I plan to do with JavaScript and CSS, but my intermediate goal is to just change some text at the bottom of the results from get.php again using JavaScript, just as a first step. But I can't seem to get any JavaScript written in get.php to fire.

Code-

This is gallery.php:

<?php
 include_once("./../php/navbar.php");
?>

<html>
<head>
 <link href="/css/siteTheme.css" rel="stylesheet">
 <style>
  .attributes span {
   margin-right: 1rem;
  }
 </style>
 <script>
 function changeParams() {
 if (window.XMLHttpRequest) {
  xmlhttp = new XMLHttpRequest();
 } else {
  xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
 }
 xmlhttp.onreadystatechange = function() {
  if (this.readyState == 4 && this.status == 200) {
   document.getElementById("test").innerHTML = this.responseText;
  }
 };
  year = document.getElementById("years_select").value;
        nameFirst= document.getElementById("nameFirst_select").value;
        /* Ton of other getElementById statements here that I'm excluding to keep things shorter */

  url = "get.php?year="+year+......;
  xmlhttp.open("GET", url, true);
  xmlhttp.send();
 } /* End function */
 </script>
</head>
<body>
<div class="content">
 <h1>Gallery</h1>
 
 <form>Details:
  <!-- -------------------- Year -------------------- -->
  <select onchange="changeParams()" name="years" id="years_select">
   <option value="All">Year</option>
 <?php
  include("/var/www/admin.php");
                $conn = mysqli_connect($dbServername, $publicdbUsername, $publicdbPass, $dbName);
                if (!$conn) {
                    die('Could not connect: ' . mysqli_error($conn));
                }
                $sql = "select year from db group by year order by year desc";
                $result = mysqli_query($conn, $sql);
                while ($row = mysqli_fetch_array($result)) {
   echo "<option value=" . $row['year'] . ">" . $row['year'] . "</option>";
                }
                mysqli_close($conn);
        ?>
  </select>
  <!-- A bunch of other selectors are created here following the same pattern as above of getting results from a DB -->

  <!-- -------------------- Searchbar -------------------- -->
  <input type="text" size="50" onkeyup="changeParams()" name="search" id="search" placeholder="Search"></input>

 </form>
 <div id="test">Choose some filters to see some results!</div>

 </form>
</div> <!-- Ends content div -->
</body>
</html>

This is get.php:

<html>
<head>
 <style>
 /* Bunch of CSS that's not relevant here */
  </style>
 <script type="text/javascript">
  console.log(".....");
  var parts = document.querySelectorAll("div.imgContainer");
  console.log("Found something:", parts);
  parts.addEventListener("click", function(){
      document.getElementById("anID").innerHTML = "Test...";
  });
 </script>
</head>
<body>
<?php
 include("/var/www/admin.php");
 $year = $_GET['year'];
 //Bunch of other variables set here following the same logic, getting data from gallery.php

 $conn = mysqli_connect($dbServername, $publicdbUsername, $publicdbPass, $dbName);
 if (!$conn) {
     die('Could not connect: ' . mysqli_error($conn));
     echo '$conn';
 }

 $sql = 'select * db';
 
 /* ---------- Creating SQL statement ---------- */
 $clauses = 0;
 if ($year != "All") {
  if ($clauses == 0) {
   $sql = $sql . ' where year = "' . $year . '" and';
   $clauses = $clauses + 1;
  } else {
  $sql = $sql . ' year = "' . $year . '" and';
  }
 } /* Bunch of other if statements to get set information and add to sql statement as such */

 // Need to chop of the last ' and' from the sql statement
 $sql = substr($sql, 0, -4);
 $sql = $sql . ' order by year desc';

 $result = mysqli_query($conn, $sql);
 $num_results = mysqli_num_rows($result);
 if ($num_results == 0 or $clauses == 0) {
  echo "<p>No matches to your query. Try refining your search terms to get some results.</p>";
 } else {
  echo "<p>" . $num_results . " results matched your query.</p>";
  echo "<div class=results>";
  //echo "<div>";

  echo '<script type="text/javascript">
    function modalFunction() {
    document.getElementById("anID").innerHTML = "test";
    }
    </script>';

  while ($row = mysqli_fetch_array($result)) {
  $pic = $row['pathToPic'];
  $wwwImg = substr($pic, 13);
   //echo "<span id=aCard><img src=" . $wwwImg . " height ='250px'>";
   //echo "<span class=text>" . $row['fullCardInfo'] . "</span></span>";
   echo "<div class=fullContainer><div class='imgContainer'><img class=image src=" . $wwwImg ."></div><p class=text>" . $row['fullInfo'] . "</p></div>";
  } // End while of results
  echo "</div>";// End results div//</div>";

  //echo '<div class="modal"><p id="anID"></p></div>';

 } // End else of "if results"
 mysqli_close($conn);
?>

<script>
 
</script>

<div>
 <p id="anID">This in a div</p>
</div>
<!--<span>
 <p id="anID">This in a span</p>
</span>-->

</body>
</html>

Sorry if that was messy, I chopped out a bunch of stuff that just gets/selects/filters some data. All that works and all variables that are left in there are set in my full code.

But the issue I'm having is writing JavaScript in get.php to change the text in the <p id="anID"> tags. I've tried JS in a few different areas of get.php, from in the <head> tags, to echoing it in <script> tags in the PHP, to pure <script> tags after the PHP statements are done (I think I left them in a few different places).

Problem is that nothing I do works to change the text in the <p> tags I references. Additionally, the console.log statements in the header of get.php don't seem to get called either. They don't fire no matter where I place them in get.php. Console.log works fine in gallery.php so it's not some issue with my browser or anything.

Long term, I will be adding JS query selectors to bring up a bigger image when an image is clicked on, but for now I'm just trying to make ANY JavaScript work in get.php and I'm struggling to do so. I don't see how this is a duplicate of the suggested repeat as I'm not trying to run JavaScript through innerHTML here.

Hollywood
  • 334
  • 4
  • 17
  • I think you have misunderstood the different languages and [how AJAX works](https://stackoverflow.com/questions/1510011/how-does-ajax-work). – Tigger Dec 08 '18 at 04:03
  • I fully admit I may not understand it fully, and see the answer I posted for something I realized, but to be honest this comment was not at all helpful – Hollywood Dec 08 '18 at 04:05
  • You may want to check out the [Getting Started](https://developer.mozilla.org/en-US/docs/Web/Guide/AJAX/Getting_Started) guide on MDN as well. – Tigger Dec 08 '18 at 04:06
  • I mean I've read Ajax guides and have a basic understanding of it. Can you tell me what I appear to be confused about? Because I'm not getting it from your links... – Hollywood Dec 08 '18 at 04:08

2 Answers2

0

Scratch that, it actually is trying to pass JavaScript through innerHTML as the information from get.php comes from this section of gallery.php:

xmlhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        document.getElementById("test").innerHTML = this.responseText;
        console.log("Response: ", this.responseText);
    }

So it appears this is a duplicate of the question I linked after all. Apologies. However, there are not great answers to that question, so any tips would be appreciated.

Hollywood
  • 334
  • 4
  • 17
0

This line:

document.getElementById("test").innerHTML = this.responseText;

Is simply going to add the contents of this.responseText to the element test. I'm sure you understand that much, but what you want to do is completely wrong. The scripts within the output of get.php will NOT be executed at all and you have corrupted your HTML as well by including a second <html><head> and more.

A better approach would be if get.php returned the data from you DB query as a JSON string like so:

$data;
while ($row = mysqli_fetch_array($result)) {
    $data[]['pic'] = $row['pathToPic'];
    $data[]['wwwImg'] = substr($row['pathToPic'], 13);
}
echo json_encode($data);
exit;

And then back on gallery.php you do something like:

if (this.readyState == 4 && this.status == 200) {
    formatResult(this.responseText);
}

// ... snip ...

function confirmJson(str) {
    var j = null;
    if (str) {
        try { j = JSON.parse(str); } 
        catch (e) { j = null; }
    }
    return j;
}
function formatResult(str) {
    var data = confirmJson(str);
    if (! data) {
        console.log("result is not JSON");
        return;
    }
    // do stuff with the data
    var i, max = data.length;
    var h = document.createElement("div");
    var img;
    for(i=0;i<max;i++) {
        img = document.createElement("src");
        img.src = data[i].wwwImg;
        img.addEventListener("click",function(){ alert("pic:["+ data[i].pic +"]"); },true);
        h.appendChild(img);
    }
    document.getElementById("test").innerHTML = h;
}
Tigger
  • 8,980
  • 5
  • 36
  • 40