Search code examples
phpajaxinfinite-scroll

How to pass the post id with AJAX in an infinite scroll


I have 15 posts(prompts in my case) that I get from the database and when a user clicks on one of them he gets sent to a detailpage of that post by giving the id with the url.

example: on the top of the page: $imagesToApprove = Prompt::get15ToApproveImages();

in the html:

<?php foreach ($imagesToApprove as $imageToApprove) : ?>
    <a href="promptDetails.php?id=<?php echo $imageToApprove['id'] ?>">
        <img src="<?php echo $imageToApprove['cover_url']; ?>" alt="prompt">
    </a>
<?php endforeach; ?>

Now I want to do the same with this infinite scroll that I have where when the user scrolls down new posts get loaded from the database, I did this with AJAX and PHP but I cant't seem to figure out how to give the id with it.

html:

<main class="flex flex-wrap">
        <div id="image-container" class="flex flex-wrap"></div>
</main>
<script src="ajax/infiniteScrollToApprove.js"></script>

AJAX file infiniteScrollToApprove.js:

var offset = 0;
var limit = 20;

// Initialize loading flag
var loading = false;

function loadImages() {
  // Set loading flag to true to prevent multiple requests from being made simultaneously
  loading = true;

  // Create new XMLHttpRequest object
  var xhr = new XMLHttpRequest();

  // Set request method, URL and headers
  xhr.open("POST", "./loadPromptsToApprove.php", true);
  xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

  // Handle response from server
  xhr.onload = function () {
    if (xhr.status === 200) {
      // Parse JSON response
      var images = JSON.parse(xhr.responseText);
      console.log("Parsed images:", images);

      // Loop through images and create img elements
      if (images.length > 0) {
        for (var i = 0; i < images.length; i++) {
          var img = document.createElement("img");
          img.setAttribute("src", images[i].cover_url);
          img.classList.add("flex", "w-1/4");
          document.getElementById("image-container").appendChild(img);
        }

        // Update offset to keep track of number of images loaded
        offset += limit;

        // Set loading flag to false to allow new requests to be made
        loading = false;
      } else {
        // If there are no more images to load, remove scroll event listener to prevent further requests
        window.removeEventListener("scroll", checkScroll);
      }
    }
  };

  // Send AJAX request with offset and limit parameters
  xhr.send("offset=" + offset + "&limit=" + limit);
}

// Function to check if user has scrolled to bottom of page
function checkScroll() {
  if (
    window.scrollY + window.innerHeight >=
    document.documentElement.scrollHeight
  ) {
    // If user has scrolled to bottom of page and no requests are currently loading, call loadImages() function to fetch new images
    if (!loading) {
      loadImages();
    }
  }
}

// Attach scroll event listener to window object to trigger checkScroll() function when user scrolls
window.addEventListener("scroll", checkScroll);

// Load initial images
loadImages();

loadToApprovePrompts:

<?php
include_once("bootstrap.php");

// Start output buffering
ob_start();

// Retrieve offset and limit values from POST request
$offset = $_POST['offset'];
$limit = $_POST['limit'];

// Retrieve array of images from database using the offset and limit values
$images = Prompt::getAllToApproveImages($offset, $limit);

// Encode the array of images as a JSON object and send it back as the response to the AJAX request
echo json_encode($images);

// Flush the output buffer
ob_end_flush();


Solution

  • Why don't you append a link tag instead of the img tag?

    AJAX file infiniteScrollToApprove.js

    var offset = 0;
    var limit = 20;
    
    // Initialize loading flag
    var loading = false;
    
    function loadImages() {
      // Set loading flag to true to prevent multiple requests from being made simultaneously
      loading = true;
    
      // Create new XMLHttpRequest object
      var xhr = new XMLHttpRequest();
    
      // Set request method, URL and headers
      xhr.open("POST", "./loadPromptsToApprove.php", true);
      xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    
      // Handle response from server
      xhr.onload = function () {
        if (xhr.status === 200) {
          // Parse JSON response
          var images = JSON.parse(xhr.responseText);
          console.log("Parsed images:", images);
    
          // Loop through images and create img elements
          if (images.length > 0) {
            for (var i = 0; i < images.length; i++) {
              var img = document.createElement("img");
              img.classList.add("flex", "w-1/4");
              img.setAttribute("src", images[i].cover_url);
              var aItem = document.createElement("a");
              aItem.setAttribute("href", "promptDetails.php?id="+images[i].id);
              aItem.appendChild(img)
              document.getElementById("image-container").appendChild(aItem);
            }
    
            // Update offset to keep track of number of images loaded
            offset += limit;
    
            // Set loading flag to false to allow new requests to be made
            loading = false;
          } else {
            // If there are no more images to load, remove scroll event listener to prevent further requests
            window.removeEventListener("scroll", checkScroll);
          }
        }
      };
    
      // Send AJAX request with offset and limit parameters
      xhr.send("offset=" + offset + "&limit=" + limit);
    }
    
    // Function to check if user has scrolled to bottom of page
    function checkScroll() {
      if (
        window.scrollY + window.innerHeight >=
        document.documentElement.scrollHeight
      ) {
        // If user has scrolled to bottom of page and no requests are currently loading, call loadImages() function to fetch new images
        if (!loading) {
          loadImages();
        }
      }
    }
    
    // Attach scroll event listener to window object to trigger checkScroll() function when user scrolls
    window.addEventListener("scroll", checkScroll);
    
    // Load initial images
    loadImages();