I want to create a progress bar for a server-side task ( written in php )
For learning purposes the example and task would be very simplistic.
I would have a text field on the client page, read a number
, pass it to the php script with ajax and make it calculate the sum of all numbers from 0 to number
( simplistic task that would take some time for big numbers, just to simulate some server-side work)
in the .html file I would create a timer that would call a function every n
seconds getting the index that my for loop got to and update a progress bar.
My question is :
Is it possible to have in the same php file two functions , and how can I call a specific function with ajax : one that would block looping to number
and another one I would call to get the current index the for-loop got to.
The code I have so far :
<!DOCTYPE html>
<html>
<head>
<script>
function myTimer()
{
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("percentageDiv").innerHTML=xmlhttp.response;
alert(xmlhttp.response);
}
}
xmlhttp.open("GET","getter.php",true);
xmlhttp.send();
}
function loop(){
var loop_index = document.getElementById("loop_nr").value;
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("sumDiv").innerHTML="Total sum = " + xmlhttp.response;
clearInterval(myVar);
}
}
xmlhttp.open("GET","server_side.php?nr="+loop_index,true);
xmlhttp.send();
var myVar=setInterval(function(){myTimer()},1000);
}
</script>
</head>
<body>
<div id="percentageDiv"> Percentage div</div>
<div id="sumDiv"></div>
<input type="text" id="loop_nr">
<input type="submit" onclick="loop()">
</body>
</html>
server_side.php
<?php
session_start();
$index=$_GET["nr"];
$progress = 0 ;
$sum = 0 ;
for ($i = 1; $i <= $index; $i++) {
$sum = $sum + $i;
$progress++;
$_SESSION['progress'] = $progress;
}
echo $sum;
?>
getter.php
<?php
session_start();
$progress = $_SESSION['progress'];
echo $progress;
?>
Thank You!
Your question would be two:
Your AJAX code is fine. The only thing you have to do in your PHP is receive this call.
Look at your request. You send a variable nr
with your request:
server_side.php?nr="+loop_index
That will help us in the php code to determine that this is an AJAX call to do the sum operation. Now in the PHP:
<?php session_start();
//We look at the GET php variable to see if the "nr" is coming
if(isset($_GET['nr'])) {
//Its coming!. Now we procede to call our function to sum
sum($_GET['nr']);
}
function sum($nr) {
$progress = 0 ;
$sum = 0 ;
for ($i = 1; $i <= $nr; $i++) {
$sum = $sum + $i;
$progress++;
$_SESSION['progress'] = $progress;
}
echo $sum;
}
Thats it.
We need to make other AJAX call to request the progress to PHP.
First, we do another AJAX call to retrieve the progress with a timer!
var timer;
//try to delete duplications. Do a generic function that does the request to php
function makeRequest(toPHP, callback) {
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
callback(xmlhttp.response);
}
}
xmlhttp.open("GET",toPHP,true);
xmlhttp.send();
}
function loop() {
var loop_index = document.getElementById("loop_nr").value;
makeRequest("server_side.php?nr="+loop_index, function(response) {
document.getElementById("sumDiv").innerHTML="Total sum = " + response;
clearInterval(timer);
});
timer=setInterval(makeRequest("getter.php", function(response) {
document.getElementById("percentageDiv").innerHTML=response;
}),1000);
}
Then in the php side we retrieve this call as we did before and echo the $_SESSION['progress']
(as you already have)
<?php
session_start();
$progress = $_SESSION['progress'];
echo $progress;
?>
And that's it!
Edit: Sessions must not be saved to a file (default PHP behaviour) because if you do that the "progress" AJAX will be blocked. You should store your sessions in a key-value database such as Redis to achieve parallelism and horizontal scalability.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With