How To Create Live Data Monitoring Page in PHP using jQuery and Ajax Tutorial

In this tutorial, we will tackle about How to Create a Live Monitoring Page in PHP and JavaScript (jQuery and Ajax). A page which automaticaly updates the data without reloading or refreshing the page. This web application feature can be meet by several methods or techniques but in this tutorial I will be using JavaScript's setInterval() function to execute a certain function for a certain time interval. This function will excute an Ajax Request which gets the updated data from the database and display it without reloading the page using jQuery.

I will be providing a simple PHP Application source code below which is Counting Posts Views. The application will automatically update the number of views in each post shown every .5 seconds. The source code uses only dummy data and randomly updates the post's views count.

Getting Started

In this tutorial, I used Bootstrap v5 for the design of application. And, kindly download also the jQuery Library. After that, compile you CSS and Script assets into a directory. Then, open your XAMPP/WAMP's Control Panel and start Apache and MySQL.

Creating the Database

Open a browser and browse the PHPMyAdmin i.e. http://localhost/phpmyadmin. Next, create a new database naming dummy_data. Then, copy the SQL script below and paste in the SQL Tab's textfield and click the Go button.

  1.         CREATE TABLE `authors` (
  2.           `id` int(11) NOT NULL,
  3.           `first_name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  4.           `last_name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  5.           `email` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
  6.           `birthdate` date NOT NULL,
  7.           `added` timestamp NOT NULL DEFAULT current_timestamp()
  8.         ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
  9.         INSERT INTO `authors` (`id`, `first_name`, `last_name`, `email`, `birthdate`, `added`) VALUES
  10.         (1, 'Emily', 'Hegmann', '[email protected]', '1979-03-16', '1976-04-05 11:59:54'),
  11.         (2, 'Miracle', 'Anderson', '[email protected]', '1975-02-02', '2006-04-13 11:34:40'),
  12.         (3, 'Kendra', 'Raynor', '[email protected]', '1979-03-19', '1987-11-17 14:51:03'),
  13.         (4, 'Simone', 'Huel', '[email protected]', '1971-09-30', '2006-05-13 21:56:04'),
  14.         (5, 'Ena', 'Harris', '[email protected]', '2010-10-27', '2004-12-06 06:04:25'),
  15.         (6, 'Emiliano', 'Kshlerin', '[email protected]', '1979-04-20', '2009-12-10 05:42:56'),
  16.         (7, 'Jedediah', 'Hermiston', '[email protected]', '1976-08-01', '1997-09-06 03:35:39');
  17.         CREATE TABLE `posts` (
  18.           `id` int(11) NOT NULL,
  19.           `author_id` int(11) NOT NULL,
  20.           `title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  21.           `description` varchar(500) COLLATE utf8_unicode_ci NOT NULL,
  22.           `content` text COLLATE utf8_unicode_ci NOT NULL,
  23.           `date` date NOT NULL
  24.         ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
  25.         INSERT INTO `posts` (`id`, `author_id`, `title`, `description`, `content`, `date`) VALUES
  26.         (1, 1, 'Adipisci incidunt qui enim libero adipisci.', 'Commodi quo aspernatur neque quasi error. Sit doloribus porro tenetur vitae. Neque doloribus reprehenderit et et ullam. Ea dolores molestiae dignissimos sed expedita dolor.', 'Eos quaerat ullam eligendi earum. Laborum occaecati sunt qui amet et sequi. Culpa quia sequi non voluptates aut omnis quia. Culpa ex porro officia voluptatibus doloribus.', '1970-07-10'),
  27.         (2, 2, 'Libero repellendus qui sit quis doloremque.', 'Modi accusamus ad totam facilis id rerum sit ipsa. Expedita labore sint velit laborum cupiditate in repudiandae.', 'Omnis et expedita sed. Qui est aut vitae quia ab suscipit. Maiores tempore et labore et inventore et. Exercitationem qui tempora rerum delectus ut facere eaque.', '1982-10-31'),
  28.         (3, 3, 'Delectus voluptatem dolorem officiis quaerat assumenda.', 'Voluptatum architecto id aliquid est. Similique dolores commodi harum minima doloribus et.', 'Nemo accusamus qui autem eos. Tempora et dolore nemo facere.', '1999-01-29'),
  29.         (4, 4, 'Excepturi voluptas saepe fugit aut saepe.', 'Laboriosam rerum aut quasi nulla. Vel atque quae fugit dolor aliquid. Voluptas ratione quod quod debitis quasi dicta. Ut ea iure est accusamus reiciendis.', 'Debitis numquam id molestiae expedita officiis. Amet natus repellendus voluptas alias. Magni ratione qui incidunt quod deleniti aut.', '1979-01-15'),
  30.         (5, 5, 'Ab dolorem nobis ut sit voluptatem aperiam minus eum.', 'Magni aliquam dolor enim rerum numquam. Impedit in modi vitae facere vitae mollitia dolor consequatur. Quas itaque adipisci labore omnis iure aut quisquam possimus.', 'Et rem tempora expedita accusamus. Inventore placeat est quisquam illo porro. Corporis dicta maiores ipsa quibusdam optio.', '1981-10-06'),
  31.         (6, 6, 'Deleniti ut provident voluptatum culpa magnam.', 'Ea magnam nihil iste minus ipsa occaecati tenetur distinctio. Aliquam mollitia nihil nihil itaque et. Laboriosam quas eveniet delectus dolore alias ipsa nesciunt. Eum repellendus optio aut illo qui quod laudantium similique. Molestiae deserunt minima harum accusamus ratione voluptates asperiores.', 'Voluptatem est aut sit et debitis ut iusto. Expedita quia facilis accusantium rerum. Accusamus quas vitae nam exercitationem aut. Quis perspiciatis commodi architecto ducimus voluptatem.', '1996-10-24'),
  32.         (7, 7, 'Omnis voluptatibus fugiat cum velit quod nostrum est ex.', 'Natus temporibus doloribus rem consequatur sit dolores veniam. Vel vel adipisci aspernatur nesciunt omnis.', 'Ut perspiciatis ut aspernatur voluptatum. Numquam velit explicabo ipsam similique quod beatae saepe nulla. Mollitia accusantium aspernatur quaerat deserunt aperiam.', '2010-08-12');
  33.  
  34.  
  35.         CREATE TABLE `views` (
  36.           `id` int(30) NOT NULL,
  37.           `post_id` int(11) NOT NULL,
  38.           `view_count` int(30) NOT NULL DEFAULT 0
  39.         ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
  40.  
  41.         INSERT INTO `views` (`id`, `post_id`, `view_count`) VALUES
  42.         (1, 1, 6712),
  43.         (2, 2, 6816),
  44.         (3, 5, 6877),
  45.         (4, 3, 6620),
  46.         (5, 7, 7449),
  47.         (6, 6, 6480),
  48.         (7, 4, 6676);
  49.         ALTER TABLE `authors`
  50.           ADD PRIMARY KEY (`id`),
  51.           ADD UNIQUE KEY `email` (`email`);
  52.  
  53.         ALTER TABLE `posts`
  54.           ADD PRIMARY KEY (`id`);
  55.         ALTER TABLE `views`
  56.           ADD PRIMARY KEY (`id`);
  57.         ALTER TABLE `authors`
  58.           MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=101;
  59.         ALTER TABLE `posts`
  60.           MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=101;
  61.         ALTER TABLE `views`
  62.           MODIFY `id` int(30) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=8;

Creating the Database Connection

Next, we will be creating our database connection. In your source code folder, create a new PHP File naming connect.php. Copy/Paste the source code below and save the file. Make sure to configure your database connection string according to your database setup.

  1.         <?php
  2.         $host='localhost';
  3.         $username="root";
  4.         $pw= "";
  5.         $db_name = "dummy_data";
  6.  
  7.         $conn = new mysqli($host, $username, $pw, $db_name);
  8.  
  9.         if(!$conn){
  10.             die('Database Connection failed. Error: '.$conn->error);
  11.         }

Creating the Interface

The script below the is the code for our Page Interface. The script queries all the posts listed in the database along with the author name and date published. The posts will be displayed with 0 counts of views by default. Save the script below as index.php

  1.         <!DOCTYPE html>
  2. <html lang="en">
  3.  
  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>Live Monitoring in PHP and jQuery/Ajax</title>
  9.     <link rel="stylesheet" href="./css/bootstrap.min.css">
  10.     <!-- Custom CSS -->
  11.     <script src="./js/jquery-3.6.0.min.js"></script>
  12.     <script src="./js/bootstrap.min.js"></script>
  13.     <script src="./js/script.js"></script>
  14.     <style>
  15.          :root {
  16.             --bs-success-rgb: 71, 222, 152 !important;
  17.         }
  18.        
  19.         html,
  20.         body {
  21.             height: 100%;
  22.             width: 100%;
  23.             font-family: Apple Chancery, cursive;
  24.         }
  25.         .fs-7 {
  26.             font-size: .8rem!important;
  27.         }
  28.     </style>
  29. </head>
  30.  
  31. <body class="bg-light">
  32.     <nav class="navbar navbar-expand-lg navbar-dark bg-primary bg-gradient" id="topNavBar">
  33.         <div class="container">
  34.             <a class="navbar-brand" href="https://sourcecodester.com">
  35.             Sourcecodester
  36.             </a>
  37.         </div>
  38.     </nav>
  39.     <div class="container py-3" id="page-container">
  40.         <small>How to create a Live Monitoring Page in PHP with jQuery/Ajax using <span class="text-primary">setInterval()</span></small>
  41.         <hr>
  42.         <h3><b>Contents Number of Views</b></h3>
  43.         <div class="col-12">
  44.             <div class="row row-cols-1 row-cols-sm-1 row-cols-md-2 row-cols-xl-3 gx-4 gy-4" id="posts">
  45.                 <?php
  46.                 include('connect.php');
  47.                 $posts = $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 unix_timestamp(p.date) desc ");
  48.                 while($row = $posts->fetch_array()):
  49.                 ?>
  50.                 <div class="col post-item">
  51.                     <div class="card rounded-0 h-100">
  52.                         <div class="card-body rounded-0">
  53.                             <h5 class="card-title text-truncate" title="<?php echo $row['title'] ?>"><?php echo $row['title'] ?></h5>
  54.                             <div class="w-100 d-flex justify-content-between">
  55.                                 <span class="text-muted fs-7"><?php echo ucwords($row['author']) ?></span>
  56.                                 <span class="text-muted fs-7"><?php echo date("M d, Y",strtotime($row['date'])) ?></span>
  57.                             </div>
  58.                             <div class="w-100 text-end mt-3">
  59.                                 <div class="fs-4 fw-bold views-count" data-id="<?php echo $row['id'] ?>">0</div>
  60.                             </div>
  61.                         </div>
  62.                     </div>
  63.                 </div>
  64.                 <?php endwhile; ?>
  65.             </div>
  66.         </div>
  67.     </div>
  68.  
  69. </body>
  70.  
  71. </html>

Creating the JavaScript Functions

Next, the following script is the JavaScript functions that updates the number of view of each views. It contains the Ajax Request and setInterval script. Save the file as script.js.

  1.         var ids = {};
  2.         var countInterval;
  3.         $(function() {
  4.             $('#posts .views-count').each(function() {
  5.                 ids[$(this).attr('data-id')] = $(this).text()
  6.  
  7.             })
  8.             countInterval = setInterval(() => {
  9.                 update_count()
  10.             }, 500)
  11.             update_count()
  12.         })
  13.  
  14.         function update_count() {
  15.             ids = {}
  16.             $('#posts .views-count').each(function() {
  17.                 ids[$(this).attr('data-id')] = $(this).text()
  18.  
  19.             })
  20.             if (ids.length <= 0) {
  21.                 // Stop Interval if no post/content
  22.                 clearInterval(countInterval)
  23.                 return false;
  24.             }
  25.             $.ajax({
  26.                 url: 'get_count.php',
  27.                 method: 'POST',
  28.                 data: { ids: ids },
  29.                 dataType: 'json',
  30.                 error: err => {
  31.                     console.log(err)
  32.                     alert("An error occured while updating the content views")
  33.                     clearInterval(countInterval)
  34.                 },
  35.                 success: function(resp) {
  36.                     if (resp.length > 0) {
  37.                         Object.keys(resp).map(k => {
  38.                             $('#posts .views-count[data-id="' + resp[k].id + '"]').text(resp[k].count)
  39.                         })
  40.                         sort_element()
  41.                     }
  42.                 }
  43.             })
  44.         }
  45.  
  46.         function sort_element() {
  47.             var sorted = $($('#posts .post-item').toArray().sort(function(a, b) {
  48.                 var Aelement = a.getElementsByClassName('views-count')[0].innerText,
  49.                     Belement = b.getElementsByClassName('views-count')[0].innerText;
  50.                 Aelement = parseFloat(Aelement.replace(/\,/gi, ''));
  51.                 Belement = parseFloat(Belement.replace(/\,/gi, ''));
  52.                 return Aelement - Belement;
  53.             }))
  54.  
  55.             Object.keys(sorted).map(k => {
  56.                 if (typeof sorted[k] == 'object') {
  57.                     var el = $(sorted[k]).clone()
  58.                     $(sorted[k]).remove()
  59.                     $('#posts').prepend(el)
  60.                     el.show('slow')
  61.                 }
  62.             })
  63.         }

Creating the PHP API

Lastly, create a new PHP File naming get_count.php. This file will updates the view count of a randow post in the database then returns the updated view count as a JSON Data.

  1.         <?php
  2.         require_once('connect.php');
  3.         // Update View Count
  4.         function update_view(){
  5.             global $conn;
  6.             $id = rand(1,7);
  7.             $check = $conn->query("SELECT id from `views` where post_id ='{$id}'")->num_rows;
  8.             $add_view = rand(1,99);
  9.             if($check > 0){
  10.                 $conn->query("UPDATE `views` set `view_count` =  `view_count` + {$add_view}  where post_id ='{$id}'");
  11.             }else{
  12.                 $conn->query("INSERT `views` set `view_count` =  {$add_view} , post_id ='{$id}'");
  13.             }
  14.         }
  15.  
  16.         $data = array();
  17.         update_view();
  18.         foreach($_POST['ids'] as $post_id => $value){
  19.             $value=str_replace(',','',$value);
  20.             // Sample Query
  21.             $views = $conn->query("SELECT view_count from `views` where post_id ='{$post_id}'");
  22.             if($views->num_rows > 0){
  23.                 $view_count = $views->fetch_array()['view_count'];
  24.                 if($value == $view_count)
  25.                     $count = 0;
  26.                 else
  27.                     $count =  $view_count;
  28.             }else{
  29.                 $count = 0;
  30.             }
  31.  
  32.             // Generate Randow Number for content view count
  33.             // $count = mt_rand(0,99999999);
  34.             if($count > 0)
  35.             $data[] = array('id'=>$post_id, 'count'=>number_format($count));
  36.         }
  37.  
  38.         echo json_encode($data);
  39.  
  40.         $conn->close();
  41.  
  42.         ?>

There you go! You can now test the simple Live Monitoring Web Application on your end. Browse the application in your browser and see if it is working according to plan. If you have encountered an error, kindly review your source code or download the working source code I created for this tutorial. The download button is located below this article.

DEMO VIDEO

That's the end of this tutorial. I hope this tutorial will help you and your future web application projects.

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

Happy Coding :)

Comments

Great

Add new comment