Progressbar

Last modified: August 12, 2009 - 06:08
  • This is a demo module which implements a progress bar
  • This demo simulates a slowish function by iterating over a sleep statement
  • On each iteration the progress is updated in the database
  • If the user has javascript it will attach an action to the 'start' link - calling the work function via ajax

Note: A demonstration of this module can be found at:
http://www.practicalweb.co.uk/progresbardemo

$.get does the magic bit

$.get(url, params, callback)

Load a remote page using an HTTP GET request.

Parameters

* url (String): The URL of the page to load.
* params (Map): (optional) Key/value pairs that will be sent to the server.
* callback (Function): (optional) A function to be executed whenever the data is loaded successfully.

see http://visualjquery.com/1.1.2.html for more detail

in this case

  • the uri is progresbardemo/work_ajax
  • there are no params to pass
  • the callback is a function that prepares to add the result of the 'work' function to the page and stop the progressbar when the ajax call completes.
  • After starting the ajax call the javascript then sets up a monitor which periodically calls /progresbardemo/monitor

    If the user doesn't have javascript enabled the link takes them to progresbardemo/work - performing the same function but without a progressbar to keep them entertained.

    <?php
    /**
    * page callback for javascript
    *
    * Normally I'd just include a javascript file
    * but I wanted to put all the code in one file for this demo
    *
    */
    function progresbardemo_javascript() {

       
    $content = '
    if (Drupal.jsEnabled) {
      $(document).ready(function() {
        $("#clickme").click(function() {
          titlediv = $("#clickme").parent();
          pb = new Drupal.progressBar(\'myProgressBar\');
          $(pb.element).appendTo("#progress");
          pb.setProgress("0", "processing...");
          uri = \'/progresbardemo/work_ajax\';
          $.get(uri , \'\', function(data) {
            $("#fillme").empty();
            $("#fillme").append(data);
            pb.stopMonitoring();
              pb.setProgress("100", "done");
          });
          pb.startMonitoring(\'/progresbardemo/monitor\', 1000);
          return false;
        })
      })
    }
        '
    ;

       
    header("Content-type: text/javascript");
        print
    $content;
        exit();
    }

    /**
    * Page callback for the demo start page
    *
    * @return html output
    */
    function progresbardemo_page() {


       
    drupal_add_js('misc/progress.js');
       
    drupal_add_js('progresbardemo/javascript');
       
    $output .= '<h2>Progress Bar Demo</h2>';
       
    $output .= '<div><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'. l('Start', 'progresbardemo/work', array('id' => 'clickme')) .'</p></div>';
       
    $output .= '<div id="fillme"></div>';
       
    $output .= '<div id="progress"></div>';
       
        return
    $output;
    }

    /**
    * Do the work
    * This function can be called directly as a menu callback where it will provide the page content
    * Or via the ajax callback function
    *
    * @return html content
    */
    function progresbardemo_work() {
       
       
    $progres = 0;
       
    db_query("insert into {variable} (name, value) values ('progresbardemo_progres', '%s')", $progres);
       
    define('PERCENT', 100);
       
    define('STEPS', 20);
        while (
    $progres < PERCENT) {
        
    sleep(1);
        
    $progres += (PERCENT / STEPS);
        
    db_query("update {variable} set value = '%s' where name = 'progresbardemo_progres'", $progres);
        }
       
    db_query("delete from {variable} where name='progresbardemo_progres'");
        return
    "<p>all done</p>";
    }

    /**
    * Do the task - called in ajax context - return the result without the page wrapper
    */
    function progresbardemo_work_ajax() {
        print
    progresbardemo_work();
        exit();

    }
    /**
    * called by the ajax monitor
    */
    function progresbardemo_monitor() {
       
    $progres = (int) db_result(db_query("select value from {variable}  where name='progresbardemo_progres'"));
       
        print
    drupal_to_js(array('status' => TRUE, 'percentage' => $progres, 'message' => "working... $progres"));
        exit();
    }






    /**
    * define the menu
    * implementation of hook_menu
    *
    * @return menu array
    */

    function progresbardemo_menu($may_cache) {
       
    $items = array();

        if (!
    $may_cache) {

           
    $items[] =  array(
                       
    'type'          => MENU_NORMAL_ITEM,
                       
    'title'             => t("Progress Bar Demo"),
                       
    'path'          => 'progresbardemo',
                       
    'callback'  => 'progresbardemo_page',
                       
    'access'        => TRUE
           
    );

           
    $items[] =  array(
                       
    'type'          => MENU_CALLBACK,
                       
    'path'          => 'progresbardemo/work',
                       
    'callback'  => 'progresbardemo_work',
                       
    'access'        => TRUE
           
    );

           
    $items[] =  array(
                       
    'type'          => MENU_CALLBACK,
                       
    'path'          => 'progresbardemo/work_ajax',
                       
    'callback'  => 'progresbardemo_work_ajax',
                       
    'access'        => TRUE
           
    );

           
    $items[] =  array(
                       
    'type'          => MENU_CALLBACK,
                       
    'path'          => 'progresbardemo/monitor',
                       
    'callback'  => 'progresbardemo_monitor',
                       
    'access'        => TRUE
           
    );

           
    $items[] =  array(
                       
    'type'          => MENU_CALLBACK,
                       
    'path'          => 'progresbardemo/javascript',
                       
    'callback'  => 'progresbardemo_javascript',
                       
    'access'        => TRUE
           
    );
        }
        return
    $items;
    }
    ?>

 
 

Drupal is a registered trademark of Dries Buytaert.