How to Limit Data to Display and Load when scrolled to bottom in PHP and jQuery Tutorial

In this tutorial, we will tackle about how limit the data to display from database and load automatically when scrolled to bottom using PHP and jQuery. This technique is very useful especially to optimize the speed of loading bulk data. This feature is commonly used in social network sites like the Facebook news feed, it shows limited posts at first and when you reached the bottom of the page, it will automatically load another data. To meet our goal for this tutorial, we will be using MySQL LIMIT and OFFSET Clause.

Getting Started

In this tutorial, I will be using Bootrstrap for the design of the web app. Also, download jQuery for our ajax functions. I'll be using XAMPP as my local web server and database server.

Before we continue, please make sure that your Apache and MySQL.

Creating the Database

Open your PHPMyAdmin in browser and create new database naming dummy_data. Import the SQL File I provided along with the source code zip file, the file is known as dummy_data.sql and located inside the db folder.

Creating Our Database Connection

Create a new PHP File and copy/paste the script below. The script contains our PHP Class for database connection. Save the file as connection.php.

  1.         <?php
  2.         $host = "localhost";
  3.         $username = "root";
  4.         $password = "";
  5.         $db_tbl = "dummy_data";
  6.  
  7.         $conn=new mysqli($host,$username,$password,$db_tbl);
  8.         if(!$conn){
  9.             die("Database Connection Failed.". $conn->error);
  10.         }

Creating the Interface

The below codes is the scripts for our page interface. Save the file as 'index.php'.

  1.         <?php
  2.         require_once('connection.php');
  3.         ?>
  4.         <!DOCTYPE html>
  5.         <html lang="en">
  6.         <head>
  7.             <meta charset="UTF-8">
  8.             <meta http-equiv="X-UA-Compatible" content="IE=edge">
  9.             <meta name="viewport" content="width=device-width, initial-scale=1.0">
  10.             <title>Load on Scroll</title>
  11.             <link rel="stylesheet" href="./css/bootstrap.min.css">
  12.             <script src="./js/jquery-3.6.0.min.js"></script>
  13.             <script src="./js/popper.min.js"></script>
  14.             <script src="./js/bootstrap.min.js"></script>
  15.             <script src="./js/script.js"></script>
  16.         </head>
  17.         <body class="bg-light">
  18.             <main>
  19.             <nav class="navbar navbar-expand-lg navbar-dark bg-primary bg-gradient" id="topNavBar">
  20.                 <div class="container">
  21.                     <a class="navbar-brand" href="./">
  22.                        Sourcecodester
  23.                     </a>
  24.                     <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
  25.                     <span class="navbar-toggler-icon"></span>
  26.                     </button>
  27.                     <div class="collapse navbar-collapse" id="navbarNav">
  28.                         <ul class="navbar-nav">
  29.                             <li class="nav-item">
  30.                                 <a class="nav-link <?php echo ($page == 'home')? 'active' : '' ?>" aria-current="page" href="./"><i class="fa fa-home"></i> Home</a>
  31.                             </li>
  32.                         </ul>
  33.                     </div>
  34.                 </div>
  35.             </nav>
  36.             <div class="container py-5 mb-4">
  37.                 <h3>Load Data when scrolled to the end</h3>
  38.                 <hr>
  39.                 <div class="col-md-8 offset-md-2" id="">
  40.                     <h4><b>Posts</b></h4>
  41.                     <hr>
  42.                     <div id="data-holder">
  43.                        
  44.                     </div>
  45.                     <div class="w-100 d-flex justify-content-center" id="loader-holder">
  46.                         <div>
  47.                             <center><div class="spinner-grow spinner-grow-sm" role="status">
  48.                                 <span class="visually-hidden">Loading...</span>
  49.                             </div>
  50.                             </center>
  51.                             <div class="text-center">Loading Data...</div>
  52.                         </div>
  53.                     </div>
  54.                     <div class="d-none text-center" id="noData"><small>You have reached the last data.</small></div>
  55.                 </div>
  56.             </div>
  57.             </main>
  58.         <div id="item_clone" class="d-none">
  59.             <div class="card shadow post-item mb-2">
  60.                 <div class="card-body">
  61.                     <h5 class="post-title"></h5>
  62.                     <p class="post-description"></p>
  63.                     <div class="w-100 d-flex justify-content-end">
  64.                         <span class="text-muted"><small><i>Author:</i> <span class="post-author"></span></small></span>
  65.                     </div>
  66.                 </div>
  67.             </div>
  68.         </div>
  69.         </body>
  70.         </html>

Creating Our Custom Javascript Functions

The code below contains the scripts for our custom js/jquery function for loading the data. In my case, I saved this file inside the js directory naming script.js. This file is included in the index.php file.

  1.         function load_data() {
  2.             $('#loader-holder').removeClass("d-none")
  3.             setTimeout(function() {
  4.                 $.ajax({
  5.                     url: "load_data.php",
  6.                     method: 'POST',
  7.                     data: { offset: $('#data-holder .post-item').length },
  8.                     dataType: 'json',
  9.                     error: err => {
  10.                         console.log(err)
  11.                     },
  12.                     success: function(resp) {
  13.                         if (resp.length > 0) {
  14.                             Object.keys(resp).map(k => {
  15.                                 var card = $('#item_clone .post-item').clone()
  16.                                 card.find('.post-title').text(resp[k].title)
  17.                                 card.find('.post-description').text(resp[k].description)
  18.                                 card.find('.post-author').text(resp[k].author)
  19.                                 $('#data-holder').append(card)
  20.                             })
  21.                         } else {
  22.                             $('#noData').removeClass("d-none")
  23.                         }
  24.                     },
  25.                     complete: function() {
  26.                         $('#loader-holder').addClass("d-none")
  27.                     }
  28.                 })
  29.             }, 800)
  30.         }
  31.         $(function() {
  32.             load_data()
  33.         })
  34.         $(window).scroll(function() {
  35.             var scrollHeight = $('body').get(0).scrollHeight;
  36.             var _scrolled = $(window).get(0).innerHeight + $(window).get(0).scrollY + 1
  37.  
  38.             if (scrollHeight <= _scrolled) {
  39.                 if ($('#noData').is(':visible') == false && $('#loader-holder').is(':visible') == false)
  40.                     load_data()
  41.             }
  42.  
  43.         });

Creating the PHP API

Lastly, copy/paste the source code below and save it as load_data.php.

  1.         <?php
  2.         require_once('connection.php');
  3.         $qry = $conn->query("SELECT p.*,concat(a.first_name,' ',a.last_name) as author FROM posts p inner join authors a on p.author_id = a.id order by id asc limit 20 OFFSET {$_POST['offset']} ");
  4.         $data = array();
  5.         while($row= $qry->fetch_assoc()){
  6.             $data[] = $row;
  7.         }
  8.         echo json_encode($data);

DEMO VIDEO

That's it! You can test your work in your browser and see if it works and meets our goal. If you encountered any errors, please review the scripts above. You can also download the working source code I created for this tutorial.

I hope this PHP and jQuery Ajax Tutorial will help you with what you are looking for and you'll find this userful for your future PHP Projects.

Happy Coding :)

Add new comment