Ajax progressbar met jQuery

Wanneer in je web applicatie opties hebt die een lange tijd nodig hebben om te voltooien, kan het makkelijk zijn om een laadbalk te tonen. Zodoende weet de bezoeker waar deze aan toe is en blijft daardoor op de site. Het maken van een progressbar op zich is niet zo moeilijk, jQuery heeft daar zelf een plugin voor. De techniek die erachter schuilt kan wat lastiger zijn. De methode die ik hier gebruik kijkt niet daadwerkelijk hoever het proces is, maar hakt het proces in stukjes. Afhankelijk van hoeveel stukjes al gedaan zijn kan uitgerekend worden hoever het proces is.

Nieuwsbrief versturen

Ik zal hier gebruik gaan maken van het versturen van een nieuwsbrief. Wanneer deze naar enkele duizenden ontvangers verstuurd moet worden, kan dat niet in één keer. Het is daarom beter om dit proces in stukjes te knippen en deze één voor één af te gaan. Hierdoor wordt de server niet in één keer zwaar belast, waardoor het proces wel afgerond kan worden.

Ik ga ervan uit dat alle nieuwsbrief leden in een tabel staan, met voornaam en achternaam. Deze moeten allemaal door de PHP mail gehaald worden. Om de pagina's in stukjes te hakken maak ik gebruik van een GET variabele genaamd page. Deze wordt vervolgens gebruikt in de MySQL query:

  1. $perKeer = 50;
  2. $page = isset($_GET['page']) ? (int)$_GET['page'] : 0;
  3. $offset = $page * $perKeer;
  4. $sql = 'select lid_voornaam, lid_achternaam, lid_email from leden';
  5. $limitSql = $sql . ' limit ' . $offset . ', ' . $perKeer;
  6. $query = mysql_query($limitSql) or die (mysql_error());
  7.  
  8. while($row = mysql_fetch_array($query)) {
  9.         $bericht = 'Beste ' . $row['lid_voornaam'] . ' ' . $row['lid_achternaam'] . "\n";
  10.         $bericht .= 'Hierbij onze nieuwsbrief, veel plezier ermee:' . "\n";
  11.        
  12.         mail($row['lid_email'], 'Nieuwsbrief', $bericht);
  13. }

We weten nu dat we elke keer 50 items uit de database halen, maar hoe kunnen wij nu terug koppelen hoever het systeem is? Door het totaal aantal rijen te tellen. Dat doen we met behulp van mysql_num_rows! Vervolgens kan de huidige voortgang hiermee berekend worden. De volgende code wordt onder de vorige code toegevoegd:

  1. $totaalQuery = mysql_query($sql) or die (mysql_error());
  2. $totaal = mysql_num_rows($totaalQuery);
  3.  
  4. $percentage = ($offset / $totaal) * 100;

Terugkoppelen

Wanneer de pagina wordt opgeroepen door een Ajax request, moet er teruggekoppeld worden hoever we zijn en welke pagina er hierna opgeroepen moet worden. Met behulp van JSON kan een PHP array aan Javascript worden doorgegeven. De PHP array wordt in de functie json_encode gegooid, waarvan de output in een echo gezet wordt.

  1. $output = array(
  2.         'percentage' => $percentage,
  3.         'next_page' => 'nieuwsbrief_versturen.php?page='. ($page + 1)
  4. );
  5. echo json_encode($output);

Progressbar vullen

Alles aan de server kant staat klaar, nu is het zaak om het geheel aan de progressbar te koppelen. Omdat er steeds Ajax requests gedaan moeten worden maken we gebruik van een functie die steeds aangeroepen wordt:

  1. function getUrl($url) {
  2.         $.ajax({
  3.                 url: $url,
  4.                 dataType: 'json',
  5.                 success: function (data) {
  6.                         $("div#progressbar").progressbar({
  7.                                 value: data.percentage
  8.                         });
  9.                        
  10.                         if(data.percentage >= '100') {
  11.                                 alert('Nieuwsbrief verstuurd!');
  12.                                 return;
  13.                         }
  14.                        
  15.                         getUrl(data.next_page);
  16.                 }
  17.         });
  18. }
  19.  
  20. $send_url = "nieuwsbrief_versturen.php?page=1";
  21. getUrl($send_url);
  22.  
  23. $( function () {
  24.         $("div#progressbar").progressbar();
  25. });

Er wordt hier een functie aangemaakt genaamd getUrl. Deze haalt de URL op, en werkt de status bar bij aan de hand van het opgegeven percentage die uit de Ajax request komt. Wanneer dit 100% is komt er een melding dat de nieuwsbrief verstuurd is. Wanneer dat niet het geval is wordt de volgende pagina opgehaald, ook weer door getUrl. Op deze manier zal het systeem pagina's blijven ophalen totdat de nieuwsbrief voor 100% verstuurd is.

Omdat de functie niet uit zichzelf zal beginnen, roep ik de eerste keer de functie handmatig aan. Hierna zal de functie zichzelf blijven aanroepen totdat deze volledig klaar is.

BijlageGrootte
jquery-progressbar.zip117.03 KB