Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asynchronously updating a Bootstrap progress bar with jQuery's $.ajax

I have a script that loops through IPs on my local network, checking if anything is there. Every iteration, I submit an AJAX request to get the HTTP status code using cURL, which is returned to my Javascript. I already have built functions to calculate where the progress bar should be, however it only updates the progress bar when the entire script is finished executing.

Here's what I have so far (I'm only using 0-23 in this example because I'm on 199.235.130.22 and I return '200')

function updateProgress(percentage){
    document.getElementById('progressBar').style.width = percentage+'%';
    $('#progressText').html(percentage+'%');
}
for(host = 0; host <= 23; host++){
    ipToCheck = network_addr+'130.'+host;
    updateProgress(100/host);
    $.ajax({
        type: 'GET',
        url: 'js/scanhelper.php',
        data: {
            ip: ipToCheck
    }
    }).done(function(msg) {
        updateProgress(100/host);
        if(msg!=0){
            logSuccess(ipToCheck);
        }
    });
    pausecomp(200);  //Just a sleep function to simulate actual processing
}

My Bootstrap HTML is simply

<div class="progress progress-striped active" style="height:44px;">
    <div id="progressBar" class="bar" style="width:1%;"></div>
</div>

And, if it matters, my cURL PHP script is here: http://pastebin.com/JRZckdVb

What this should do is, on every iteration, update the progress bar's width to 100 (as in 100%) divided by the current iteration. It may not be the correct math, but the point is it's only updating after all iterations are complete, freezing the page while it's running.

How can I fix this?

like image 203
Scott Avatar asked Dec 20 '12 13:12

Scott


1 Answers

aren't you dividing by zero here when host = 0 in the for loop?

updateProgress(100/host);

you can use a variable hosts to keep track of the number of hosts you have.Then the progress will be as below.

var hosts = 23;// total number of hosts
updateProgress((host/hosts)*100);

The other thing is the ajax you're firing is asynchronous, so what's happening is it fires and doesn't wait for the results. You can either "scan" each host serially one at a time updating the progress bar or scan all of them simultaneously having the progress bar update as the asynch results come back. Can you specify which behavior you're trying to achieve?

[UPDATE] toggle async flag in the ajax call below for what you want.

function updateProgress(percentage){
    if(percentage > 100) percentage = 100;
    $('#progressBar').css('width', percentage+'%');
    $('#progressBar').html(percentage+'%');
}

var hosts = 23;
var hostsDone = 0;
for(host = 0; host <= hosts; host++){
    ipToCheck = network_addr+'130.'+host;
    $.ajax({
        type: 'GET',
        url: 'js/scanhelper.php',
        async:true,
        data: {
            ip: ipToCheck
    }
    }).done(function(msg) {
        hostsDone++;
        updateProgress((hostsDone/hosts)*100);
        if(msg!=0){
            logSuccess(ipToCheck);
        }
    });
}

if you're looking for visuals you should set the height of '#progressBar' to something non-zero and maybe background green.

<div class="progress progress-striped active" style="height:44px;">
    <div id="progressBar" class="bar" style="height:44px;width:1%;background-color:green"></div>
</div>
like image 157
zer0bit Avatar answered Nov 03 '22 00:11

zer0bit