Loading PHP-Ajax Progress Bar

Monday, February 15, 2016

Biasanya, untuk loading proses, kita akan gunakan ajax $(document).ajaxStart(function() dan form post seperti sebelum ini. Selagi proses sedang berjalan, kita akan tunggu dengan dipaparkan animated gif sahaja.

Tetapi sekiranya kita mahu melihat status proses yang sedang berlaku dalam bentuk persen, kita perlu semak status selang beberapa masa. Mungkin setiap 1 saat. Kaedah ini diolah dari post asal di sini.

Bagi menjalankan proses ini, beberapa file perlu diwujudkan.

1. Database table untuk status.
2. File index.php untuk paparan utama.
3. File javascript jQuery terkini.
4. File config.php untuk connect ke database.
5. File process.php bagi menjalankan proses.
6. File checker.php bagi menyemak status setiap selang masa.

Secara ringkasnya begini,

1. Database table untuk status.

Bina satu table di mana table tersebut akan menyimpan jumlah keseluruhan data yang berkaitan, jumlah data yang sedang di proses, dan status proses itu sendiri. Table ini akan selalu dikemaskini oleh process.php dan disemak dengan kerap oleh checker.php.

CREATE TABLE `main_issue` (
  `issue_id` int(11) NOT NULL,
  `issue_title` varchar(120) NOT NULL,
  `issue_operating` int(1) NOT NULL DEFAULT '0' COMMENT '0=free, 1=operating',
  `issue_opscurr` int(11) NOT NULL COMMENT 'current operation',
  `issue_total` int(11) NOT NULL COMMENT 'total operation'
);

ALTER TABLE `main_issue`
  ADD PRIMARY KEY (`issue_id`);

issue_operating : Jika nilainya 0, process telah selesai. Jika nilainya 1, proses sedang berjalan. Ini bagus bagi mengawal perintah proses baru ketika proses sediada sedang berjalan.

issue_opscurr : Nilai ini akan ditambah setiap masa. Bermula dengan 0, sehinggalah cukup kesemuanya. process.php akan update setiapkali gelung selesai berpusing dan checker.php akan semak nilai di sini pada setiap selang masa.

issue_total : Nilai ini akan diupdate kali pertama oleh process.php setelah dikenalpasti jumlah data yang hendak di process. Jadi, dengan nilai jumlah keseluruhan ini, mudahlah mahu buat kiraan dalam persen nanti.

 

2. File index.php paparan utama

Disinilah kita akan paparkan progress-bar, suruh process dibelakang buat kerja, dan check status setiap sela masa (untuk contoh ini, setiap 1 saat).
<?php
session_start();
?>
<!DOCTYPE html>
<html>
<head>
  <title>Progress Bar</title>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
  <style>
    #progress {
      width: 500px;
      border: 1px solid #aaa;
      height: 20px;
    }
    #progress .bar {
      background-color: #ccc;
      height: 20px;
    }
  </style>
</head>
<body>
  <div id="progress"></div>
  <div id="information"></div>
  
  <script>
    var timer;

    function refreshProgress() {
      $.ajax({
        url: "checker.php",
        success:function(data){
          $("#progress").html('<div class="bar" style="width:' + data.percent + '%"></div>');
    //$("#progress").html('<progress max="100" value="' + data.percent + '"></progress>');
    $("#information").html("[ " + data.percent + "% ] " + data.message);
          if (data.percent == 100) {
            window.clearInterval(timer);
            timer = window.setInterval(completed, 1000);
          }
        }
      });
    }

    function completed() {
      $("#message").html("Completed");
    //$("#progress").hide();
    window.clearInterval(timer);
    }

    // Apabila page di buka. Sama seperti onload
    $(document).ready(function(){
      // Trigger proses di web server.
      $.ajax({url: "process.php"});
      // Refresh setiap 1 saat, dan panggil function refreshProgress di atas.
      timer = window.setInterval(refreshProgress, 1000);
    });
  </script>
</body>
</html>

 

3. File jquery

File jquery boleh dipanggil terus melalui web, atau download siap-siap dan panggil pada folder sahaja.

<head>
  <title>Progress Bar</title>
  <!-- Dapatkan jquery dari google -->
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
  <!-- ATAU, dapatkan dari local sendiri. Tapi pastikan filenya ada. -->
  <script src="jquery-1.11.2.min.js"></script>
  

 

Jangan guna kedua-dua sekaligus. Pilih salah satu.

 

4. File config.php connect database

File config.php ini cuma setting database connection. Jika tak ada pun, boleh sahaja gunakan code connection terus pada file PHP yang memerlukannya. File config ini sekadar memudahkan code connection sahaja. Cuma include jika memerlukan.

<?php
$con = mysql_connect("localhost", "root", "", true);  
if (!$con)
{
  die('Could not connect MySQL-Internal : ' . mysql_error());
}
mysql_select_db("midataclean", $con);

?>

 

5. File process.php

Bagi menjalankan proses php di background. Ajax cuma akan beri arahan untuk process.php buat kerja.

<?php
include('config.php');
session_start();

$sqla = "SELECT issue_operating FROM main_issue WHERE issue_id = 1";
$resa = mysql_query($sqla, $con) or trigger_error("Query failed!: ".$sqla);
while ($row = mysql_fetch_array($resa, MYSQL_ASSOC))
{
 $iss_operating = $row['issue_operating'];
}

if($iss_operating == '0') {
 $sql ="SELECT * FROM table WHERE 1";
 $result = mysql_query($sql,$con);
 $total = mysql_num_rows($result);
 // The example total processes. Dapatkan $total dari database.
 //$total = 20;

 //Update status database. Jumlah dan status sedang beroperasi
 $sql ="UPDATE main_issue SET issue_total='".$total."', issue_operating='1' WHERE issue_id='1'";
 $result = mysql_query($sql,$con);
  
 // Pusingan loop
 for($i=1; $i<=$total; $i++){
   // Calculate the percentation
   $percent = intval($i/$total * 100);
   
   //UPDATE/DELETE/INSERT database jika mahu buat sesuatu
   //atau sekadar SELECT satu persatu data.
   $sqlb ="UPDATE pengguna SET pengguna_level ='5' WHERE pengguna_id ='".$i."'";
   $resultb = mysql_query($sqlb,$con);
      
   //Nilai semasa yang sedang looping, update counter terkini ke dalam field
   $sqla ="UPDATE main_issue SET issue_opscurr = '".$i."' WHERE issue_id='1'";
   $resulta = mysql_query($sqla,$con);

   // Jika kiraan nilai semasa sudah sama banyak dengan total, bolehlah update status operasi = 0. Iaitu status dah selesai.
  if($i==$total) {
     //update database sekali
     $sqlu ="UPDATE main_issue SET issue_operating='0' WHERE issue_id='1'";
     $resultu = mysql_query($sqlu,$con);
  }
  
   // Sleep one second so we can see the delay
   // Jika data banyak, tak perlu sleep. 
   // Sleep sekadar nak visualize di index.php sebab data sikit, progress bolehlah nampak berjalan perlahan.
   sleep(1); //1 second
   //usleep(100000); //0.1 second 
 }
}
?>

 

6. File checker.php

Checker.. data dalam bentuk JSON.

<?php
// The file has JSON type.
header('Content-Type: application/json');

include('config.php');

$sql = "SELECT issue_operating, issue_opscurr, issue_total FROM main_issue WHERE issue_id = 1";
$res = mysql_query($sql, $con) or trigger_error("Query failed!: ".$sql);
while ($row = mysql_fetch_array($res, MYSQL_ASSOC))
{
 $iss_operating = $row['issue_operating'];
 $iss_opscurr = $row['issue_opscurr'];
 $iss_total = $row['issue_total'];
}

$percent = intval($iss_opscurr/$iss_total * 100);
$msg = $iss_opscurr."/".$iss_total." rekod sedang diproses.";
echo json_encode(array("percent" => $percent, "message" => $msg));

?>

0 comments: