0

I have tried doing this but couldn't get it. Below is my code :

<script> 
    $(document).ready(function(){
        var $progressbar = $("#progressbar");
        $progressbar.show();
        $('#uploadForm').on('submit', function(e){
            e.preventDefault();
            $(function(){
                $progressbar.css('width', '30%');
            }); 
            $.ajax({
                url: "insertdata.php",
                type: "POST",
                data: new FormData(this),
                contentType: false,
                processData: false,
                success: function(data){
                    console.log(data);
                    if (data == 'T'){
                        $('#txtname').val("");
                        $('#txtsex').val("");
                        $('#txtage').val("");
                        $('#txterr').val('Record Inserted');
                        $progressbar.css('width', '100%');
                    }
                },
                error: function(data){
                alert("Something went wrong !");
            }
        });
    });
});
</script>

Code for Progress bar is as follows:

<div class="progress" style="margin-top:100px">
    <div class="progress-bar active" id="progressbar" role="progressbar" aria-valuenow="45" aria-valuemin="0" aria-valuemax="100" style="width: 0%">
        <span class="sr-only">0% Complete</span>
    </div>
</div>

insertdata.php In this file, data insertion is processed.

Here working of my code is something like this: when the user presses the "Submit" button, progress bar shows 30% increase and when the process finishes 30% moves to 100%.

What I want to achieve is : Progress Bar should show progress ( percent by percent ) with the insertion of data into database, after Submit button is pressed.

How to achieve this?

Please help

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Ratan
  • 9
  • 1
  • 7
  • 1
    assuming you're inserting multiple rows, you're not going to know how far along the inserting is going if you're inserting all in one hit. in saying that, if you insert one row at a time for the sake of tracking progress for the progress bar, it would result in multiple hits to the insert script, and imo is a waste of resources. – flauntster Nov 08 '16 at 05:58
  • Consider measuring the average time to insert, and use a simple animation of that average, its a lie, but it works for the UEx – Ricardo Ortega Magaña Nov 08 '16 at 06:26
  • http://stackoverflow.com/questions/20453015/progress-bar-ajax-and-php – Aston Nov 08 '16 at 11:17

1 Answers1

3

Today I have a working example for you. I try to highlight the important parts.

First of all the PHP File that "does something", I called it progress.php:

progress.php

<?php

if (strlen(session_id()) === 0) {
    session_start();
}
makeProgress();

function makeProgress() {
    $progress = 0;
    $max = 100;
    for ($i = 1; $i <= $max; $i++) {
        if (isset($_SESSION['progress'])) {
            session_start(); //IMPORTANT!
        }
        $progress++;
        $_SESSION['progress'] = $progress;
        session_write_close(); //IMPORTANT!
        sleep(1); //IMPORTANT!
    }
}

A Session is opened for our progress to be stored in.

Now the function makeProgress is started and runs a loop that count progress up and sleeps for a second, before it counts up again.

The Session is write_closed, the script sleeps for a second and after that the session is started again. This is important to give other workers access to Session and working time. Without closing, the Session would be stalled until the makeProgress loop is finished, without sleep no other script gets "Servertime" to do something and would be stalled till the end of the loop.

Next the PHP File that gets the progress:

getProgress.php

<?php

if (strlen(session_id()) === 0) {
    session_start();
}

if (isset($_SESSION['progress'])) {
    echo $_SESSION['progress'];
    if ($_SESSION['progress'] == 100) {
        unset($_SESSION['progress']);
    }
} else {
    echo '0';
}

This is quite simple, it just starts the session and returns whats in our Session Variable. It also unsets the Variable if 100% is reached.

Now the glue, Javascript file: progress.js

$('document').ready(function () {
    $('#startProgress').click(function () {
        getProgress();
        console.log('startProgress');
        $.ajax({
            url: "progress.php",
            type: "POST",
            data: {
                'startProgress': 'yes'
            },
            async: true, //IMPORTANT!
            contentType: false,
            processData: false,
            success: function(data){
                if(data!==''){
                    alert(data);
                }
                return false;
            }
        });
        return false;
    });

});

function getProgress() {
    console.log('getProgress');
    $.ajax({
        url: "getProgress.php",
        type: "GET",
        contentType: false,
        processData: false,
        async: false,
        success: function (data) {
            console.log(data);
            $('#progressbar').css('width', data+'%').children('.sr-only').html(data+"% Complete");
            if(data!=='100'){
                setTimeout('getProgress()', 1000);
            }
        }
    });
}

Setting your startProgress ajax call to async: true is important, otherwise your Browser would stall and wait for the long executing script to respond. The getProgress function is started when you click the button and executed again every Second as long as the returned data is not 100. Simple.

In the end there is an html file, making progress visible:

progress.html

<!DOCTYPE html>
<html>
    <head>
        <title>TODO supply a title</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <script type="text/javascript" src="jquery-1.9.1.min.js"></script>
        <script type="text/javascript" src="progress.js"></script>
    </head>
    <body>
        <form action="progress.php" method="POST" >
            <input id="startProgress" type="submit" name="startProgress" value="start progress"/>
        </form>
        <div class="progress" style="margin-top:100px">
            <div class="progress-bar active" id="progressbar" role="progressbar" aria-valuenow="45" aria-valuemin="0" aria-valuemax="100" style="width: 0%; background-color: #399;">
                <span class="sr-only">0% Complete</span>
            </div>
        </div>
    </body>
</html>

Now see the working example in Action and Download all those files I used here:

https://9tw.de/~testArea/progress/progress.html

Things that need to be addressed: Since the initial ajax call is async, it is possible to click it more than one time, what will cause the progress bar to fluctuate (since now there are 2 to n scripts running simultaneously and writing to the same Session Variable). You might want to block a second click until the current process is finished.

Another Thing: if you sleep every second for one second, the script execution time will double. You need to find a good compromise between executing time and progressbar updates.

There are other (even better) technics to implement progress bars, like Threading, but since Threading is quite rarely compiled into PHP, this should be the most (hoster-)compatible solution to date.

Happy Coding.

mondjunge
  • 1,219
  • 14
  • 24
  • Thanks,, I have tried adding the "progress:function(evt)" part, but nothing is happening means progress bar is not incrementing along, when the button is pressed. May be I am doing something wrong. Can you please guide me how to use this function by providing me some example. – Ratan Nov 08 '16 at 15:29
  • I would like to, but have not much time. I think my script only works for uploading files. Here is an article on the topic, that might interests you: http://www.htmlgoodies.com/beyond/php/show-progress-report-for-long-running-php-scripts.html – mondjunge Nov 08 '16 at 16:49
  • does anyone has some idea?? – Ratan Nov 08 '16 at 18:44
  • 1
    iam here because i noticed a edit on this question/answer.. i find it very wierd to find two `session_start()` on two locations in one PHP file, but for the rest it seams to be solid + 1 – Raymond Nijland Jun 20 '19 at 16:19
  • @RaymondNijland that is the trick. The second session_start is in the for loop. The session gets closed at the end of every iteration, so it has to be opened again on the next iteration. This is needed in order to make the session variabel accessible for the other PHP script, before the loop reaches 100. – mondjunge Jun 20 '19 at 16:25
  • 1
    Oh yes offcource that makes sense more or less as the `session_write_close()` will close the session file .. But still a rewrite would/should not require two `session_start()` used in a one file which possible can cause a error. – Raymond Nijland Jun 20 '19 at 16:30
  • As I said, you need to close the session between iterations or the first script will stall the session until it reaches 100, what makes it impossible for the second script to read the Session while the first script counts up the progress counter. You might be able to write it more compact, but I thrive for readability, not for the most clever construct of code. – mondjunge Jun 26 '19 at 08:12