List Pagination using PHP, jQuery, and Ajax Tutorial

In this tutorial, you will learn how to add a Pagination Feature in your HTML List loaded from the Database. Here, you can achieve the said feature in your project with the use of jQuery library and Ajax Request. This feature is very helpful to optimize the load duration of your website in terms of loading a page with a bulk list data.

Bulk data can affect the speed of loading your site page. At first, when the project is still fresh, you won't notice the slow loading of the site page because the data is not that large yet. But with the use of Pagination Feature, this will prevent slow page loading in your project in the future. And also, with the help of the jQuery Library this will give your end-users a better experience.

Getting Started

Download and Install any local web server such as XAMPP/WAMP so you can run the simple web application that we will be making on your end.

If you use XAMPP/WAMPP, open the software's Control Panel and start Apache and MySQL servers.

Also, download Bootstrap v5 and jQuery Library. After that compile the libraries in a directory that you will use for storing your source code.

Note: If you are using XAMPP, make sure that your source code folder is stored inside the htdocs directory while in WAMP, place it on the www directory.

Creating the Dummy Database

Open a new tab in your browser and browse the PHPmyAdmin i.e https://localhost/phpmyadmin. Create a new database naming dummy_db. I have provided a dummy SQL Data in this article, you can download the source code zip file below this article. Then, import into your newly created database the dummy_db.sql file from the db directory in the download source code.

Creating The Custom Style Sheet

Below is the a simple CSS (Cascading Style Sheet) script for the custom design of some part of the application. Save this file as custom.css

  1. :root {
  2. --bs-success-rgb: 71, 222, 152 !important;
  3. }
  4.  
  5. html,
  6. body {
  7. height: 100%;
  8. width: 100%;
  9. font-family: Apple Chancery, cursive;
  10. }
  11.  
  12. .btn-info.text-light:hover,
  13. .btn-info.text-light:focus {
  14. background: #000;
  15. }
  16.  
  17. #pgn-container {
  18. position: relative;
  19. }
  20.  
  21. #pgn-loader {
  22. position: absolute;
  23. height: calc(100%);
  24. width: calc(100%);
  25. background-color: rgba(17, 17, 17, 0.432);
  26. display: flex;
  27. justify-content: center;
  28. align-items: center;
  29. z-index: 2;
  30. }
  31.  
  32. .list-group[data-placeholder="true"]:empty:after {
  33. content: "No Data to Display";
  34. align-self: center;
  35. font-style: italic;
  36. font-size: .8em;
  37. color: rgb(66, 66, 66);
  38. }

Creating the Database Connection

Below is the script that that allow our script to connect to the MySQL Database. Save this file as db-connect.php.

  1. <?php
  2. // Dummy Data
  3. $host = 'localhost';
  4. $username = 'root';
  5. $password = '';
  6. $dbname = 'dummy_db';
  7.  
  8. $conn = new mysqli($host, $username, $password, $dbname);
  9.  
  10. if(!$conn){
  11. die("Database Connection failed. ".$conn->error);
  12. }

Creating the Interface

The script below is the code of the elements of our interface. It contains the navigation bar, List Element, Pagiation Buttons, and more. Save this file as index.php.

  1. <?php require_once('db-connect.php') ?>
  2. <!DOCTYPE html>
  3. <html lang="en">
  4. <head>
  5. <meta charset="UTF-8">
  6. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  7. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  8. <title>Paginatation</title>
  9. <link rel="stylesheet" href="./Font-Awesome-master/css/all.min.css">
  10. <link rel="stylesheet" href="./css/bootstrap.min.css">
  11. <link rel="stylesheet" href="./css/custom.css">
  12. <script src="./js/jquery-3.6.0.min.js"></script>
  13. <script src="./js/bootstrap.min.js"></script>
  14. <script src="./js/script.js"></script>
  15. </head>
  16.  
  17. <body class="bg-light">
  18. <nav class="navbar navbar-expand-lg navbar-dark bg-dark bg-gradient" id="topNavBar">
  19. <div class="container">
  20. <a class="navbar-brand" href="https://sourcecodester.com">
  21. Sourcecodester
  22. </a>
  23.  
  24. <div>
  25. <b class="text-light">Pagination using jQuery and Ajax</b>
  26. </div>
  27. </div>
  28. </nav>
  29. <div class="container py-5" id="page-container">
  30. <!-- Table Container -->
  31. <div id="pgn-container">
  32. <div class="text-center" id="pgn-loader">
  33. <div class="spinner-border text-primary" role="status">
  34. <span class="visually-hidden">Loading...</span>
  35. </div>
  36. </div>
  37. <div class="row">
  38. <div class="col-sm-12 col-md-6">
  39. <span><b>Total Records:</b> <span class='total-records'>0</span></span>
  40. </div>
  41. <div class="col-sm-12 col-md-6 text-end">
  42. <span><b>Showing</b> <span class='show-filter'></span></span>
  43. </div>
  44. </div>
  45. <!-- List Field -->
  46. <ul class="list-group" data-placeholder="true"></ul>
  47. <!-- End of List Field -->
  48. <div class="col-md-12 my-2">
  49. <div class="row">
  50. <div class="justify-content-center">
  51. <div class="btn-group me-2" role="group" aria-label="First group">
  52. <button type="button" id="prev-page" class="btn btn-outline-secondary"><i class="fa fa-caret-left"></i></button>
  53.  
  54. <button type="button" id="next-page" class="btn btn-outline-secondary"><i class="fa fa-caret-right"></i></button>
  55. </div>
  56. </div>
  57. </div>
  58. </div>
  59. </div>
  60. <!-- End of Table Container -->
  61. </div>
  62. <!-- List Item Clone Element -->
  63. <noscript id="list-item-clone">
  64. <li class="list-group-item list-group-item-action pgn-item">
  65. <h3 class="fw-bold item-title"></h3>
  66. <hr>
  67. <p class="item-description"></p>
  68. </li>
  69. <!-- End of List Item Clone Element -->
  70.  
  71. <!-- Page Button Clone -->
  72. <noscript id="ipage-clone">
  73. <button type="button" class="btn btn-outline-secondary ipage-btns"></button>
  74. <!-- End of Page Button Clone -->
  75.  
  76. </body>
  77. <?php if(isset($conn)) $conn->close(); ?>
  78. </html>

Creating the PHP API

The below script is the PHP code that fetches the records in the database, counts the filtered and total records in the database, and the count of page buttons. Save this file as get_data.php.

  1. <?php
  2. require_once('db-connect.php');
  3. // array to send back
  4. $resp = [];
  5. // Limit data to display
  6. $limit = 5;
  7. if($_SERVER['REQUEST_METHOD'] =='POST'){
  8. $page = $_POST['page'];
  9. // Total Records
  10. $all_posts = $conn->query("SELECT * FROM `posts`");
  11. $total_data = number_format($all_posts->num_rows);
  12. $resp['total'] = $total_data;
  13.  
  14. // total page count
  15. $resp['page_count'] = ceil($total_data / $limit);
  16.  
  17. $offset = $page > 0 ? $page * $limit : 0;
  18.  
  19. // Filtered Data
  20. $posts = $conn->query("SELECT * FROM `posts` order by `id` limit $limit offset $offset");
  21. $resp['total_filtered'] = number_format($posts->num_rows);
  22. $resp['filtered'] = number_format($offset + 1)." - ". number_format($offset + $posts->num_rows);
  23. while($row = $posts->fetch_assoc()){
  24. $row['title'] = $row['id'] . " - ".$row['title'];
  25. $row['description'] = str_replace("\n","<br/>",$row['description']);
  26. $resp['data'][] = $row;
  27. }
  28. }
  29. echo json_encode($resp);
  30. $conn->close();
  31. ?>

Creating the JavaScript File

The below is script is the JavaScript codes which contains all the functions that loads, redirects, and displays the data. Save this file as script.js.

  1. // current page loaded
  2. var current_page = 0;
  3. // Vount of records
  4. var _total = 0
  5. window.pgn_loader_start = function() {
  6. $('#pgn-loader').removeClass('d-none')
  7. }
  8. window.pgn_loader_end = function() {
  9. $('#pgn-loader').addClass('d-none')
  10. }
  11. window.load_page_bts = function($count = 1) {
  12. $('#pgn-container .ipage-btns').remove()
  13. for (var i = 0; i < $count; i++) {
  14. var btn = $($('noscript#ipage-clone').html()).clone()
  15. btn.attr('data-page', i)
  16. btn.text(parseFloat(i + 1).toLocaleString())
  17. $('#pgn-container #next-page').before(btn)
  18. btn.click(function() {
  19. load_page($(this).attr('data-page'))
  20. })
  21. }
  22. $('#pgn-container .ipage-btns[data-page="' + current_page + '"]').addClass('active')
  23. if (current_page == 0) {
  24. $('#prev-page').attr('disabled', true)
  25. } else {
  26. $('#prev-page').attr('disabled', false)
  27. }
  28. if (current_page == (_total - 1)) {
  29. $('#next-page').attr('disabled', true)
  30. } else {
  31. $('#next-page').attr('disabled', false)
  32. }
  33. }
  34. window.load_page = function($page = 0) {
  35. current_page = $page
  36. pgn_loader_start();
  37. $.ajax({
  38. url: './get_data.php',
  39. method: 'POST',
  40. data: { page: $page },
  41. dataType: 'json',
  42. error: err => {
  43. console.error(err)
  44. alert("An error occurred while fetching data.")
  45. pgn_loader_end();
  46. },
  47. success: function(resp) {
  48. if (resp) {
  49. $('#pgn-container ul').html('')
  50. var data = resp.data || {};
  51. $('#pgn-container .total-records').text(resp.total)
  52. $('#pgn-container .show-filter').text(resp.filtered)
  53.  
  54. // Load Pagination Buttons
  55. load_page_bts(resp.page_count)
  56. _total = resp.page_count
  57.  
  58. Object.keys(data).map(k => {
  59. var li = $($('noscript#list-item-clone').html()).clone()
  60. li.find('.item-title').text(data[k].title)
  61. li.find('.item-description').text(data[k].description)
  62. $('#pgn-container ul').append(li)
  63. })
  64. } else {
  65. console.error(resp)
  66. alert("An error occurred while fetching data.")
  67. }
  68. setTimeout(() => {
  69. pgn_loader_end();
  70.  
  71. }, 800)
  72. }
  73. })
  74. }
  75.  
  76. $(function() {
  77. load_page()
  78. $('#prev-page').click(function() {
  79. load_page(current_page - 1)
  80. })
  81. $('#next-page').click(function() {
  82. load_page(current_page + 1)
  83. })
  84. })

That's it! You can now test the application in your browser and see if we have met our goal on this tutorial. If ever you have encountered any errors, please review your source code by differentiating it from the source code I provided above. You can also test the working source code I created for this tutorial. You can download the source code zip file below this article.

DEMO VIDEO

That is the end of this tutorial. I hope you'll find this List Pagination Tutorial useful for you current and future PHP projects.

Explore more on this website for more Tutorials and Free Source Codes.

Happy Coding :)

Add new comment