HTML_Progress
[ class tree: HTML_Progress ] [ index: HTML_Progress ] [ all elements ]
Prev Next

Using Indeterminate Mode

how to animate a progress bar to show unknown length-task activity

by by Laurent Laville
mailto:pear@laurent-laville.org
April 2004, Laurent Laville
(HTML_Progress 1.2+)

Table of Contents

Introduction

Sometimes you can't immediately determine the length of a long-running task, or the task might stay stuck at the same state of completion for a long time. You can show work without measurable progress by putting the progress bar in indeterminate mode. A progress bar in indeterminate mode displays animation to indicate that work is occurring. As soon as the progress bar can display more meaningful information, you should switch it back into its default, determinate mode. The look and feel of indeterminate progress bars look like this:

Using Indeterminate Mode

In example that follow, we have created a Task Class that extends the default monitoring HTML_Progress_Monitor class.

The most important code additions are calls to the HTML_Progress::setIndeterminate() method. When the user clicks the Start button, setIndeterminate(true) is invoked (line 143) so that the user can tell that the task as started, even before any meaningful information about the task's progress can be conveyed. Once the progress bar has some concrete status to display, a call to setIndeterminate(false) (line 76) switches the progress bar back into its normal mode. The HTML_Progress::isIndeterminate() method (line 75) is used to test the progress bar's current state.

The other changes in the code are related to string display. A progress bar that displays a string is likely to be taller than one that doesn't, and, as the demo designers, we've arbitarily decided that this progress bar should display a string only when it's in the default, determinate mode. However, we want to avoid the layout ugliness that might result if the progress bar changed height when it changed modes. Thus, the code leaves in the call to HTML_Progress::setStringPainted() method with true value (line 39), but adds a call to HTML_Progress::setString() method (line 40) with empty string value, so that no text will be displayed. Later, when the progress bar switches from indeterminate to determinate mode, invoking setString(null) (line 77) makes the progress bar display its default string.

One change we did not make was removing the call to HTML_Progress::setValue() from the timer's action handler (notify method). The call doesn't do any harm because an indeterminate progress bar doesn't use its value property, except perharps to display it in the status string. In fact, keeping the progress bar's data as up-to-date as possible is a good practice, since some look and feels might not support indeterminate mode.

Full example listing

  1. <?php
  2. require_once ('HTML/Progress/monitor.php');
  3.  
  4. class Task extends HTML_Progress_Monitor
  5. {
  6.     var $_current;
  7.     
  8.     function Task()
  9.     {
  10.         $this->_current = 0;
  11.         $this->_id md5(microtime());
  12.  
  13.         $this->_form = new HTML_QuickForm('ProgressBarDialog');
  14.  
  15.         $renderer =$this->_form->defaultRenderer();
  16.         $renderer->setFormTemplate('
  17.             <table width="450" border="0" cellpadding="3" cellspacing="2" bgcolor="#CCCC99">
  18.             <form{attributes}>{content}
  19.             </form>
  20.             </table>
  21.             ');
  22.         $renderer->setHeaderTemplate('
  23.             <tr>
  24.         <td style="white-space:nowrap;background:#996;color:#ffc;" align="left" colspan="2"><b>{header}</b></td>
  25.         </tr>
  26.         ');
  27.         
  28.         $this->_form->addElement('header''windowsname''Progress...');
  29.         $this->_form->addElement('static''progress');
  30.         $this->_form->addElement('static''status');
  31.  
  32.         $buttons[&HTML_QuickForm::createElement('submit''start',  'Start',  'style="width:80px;"');
  33.         $buttons[&HTML_QuickForm::createElement('submit''cancel''Cancel''style="width:80px;"');
  34.         $this->_form->addGroup($buttons);
  35.  
  36.         
  37.         $this->_progress = new HTML_Progress();
  38.         $this->_progress->setAnimSpeed(100);
  39.         $this->_progress->setIncrement(10);
  40.         $this->_progress->setStringPainted(true);     // get space for the string
  41.         $this->_progress->setString("");              // but don't paint it
  42.  
  43.         $ui $this->_progress->getUI();
  44.         $ui->setProgressAttributes(array(
  45.             'background-color' => '#e0e0e0'
  46.                 ));        
  47.         $ui->setStringAttributes(array(
  48.                 'color'  => '#996',
  49.             'background-color' => '#CCCC99'
  50.                 ));        
  51.         $ui->setCellAttributes(array(
  52.                 'active-color' => '#996'
  53.                 ));
  54.  
  55.         $bar =$this->_form->getElement('progress');
  56.         $bar->setText$this->_progress->toHtml() );
  57.  
  58.         $str =$this->_form->getElement('status');
  59.         $str->setText('<div id="status" style="color:#000000; font-size:10px;">&nbsp;</div>');
  60.  
  61.         $this->_progress->addListener($this);
  62.     }
  63.  
  64.     function notify($event)
  65.     {
  66.         if (is_array($event)) {
  67.             $log strtolower($event['log']);
  68.             $val $event['value'];
  69.             
  70.             switch (strtolower($log)) {
  71.              case 'incvalue':
  72.              case 'setvalue':
  73.                  $this->_current $this->getCurrent(+ 16;
  74.                  $s $this->getMessage();
  75.                  if (!is_null($s)) {
  76.                      if ($this->_progress->isIndeterminate()) {
  77.                          $this->_progress->setIndeterminate(false);
  78.                          $this->_progress->setString(null);      // display % string
  79.                          $this->_progress->setValue(0);
  80.                      }
  81.                      if ($this->isDone()) {
  82.                          $this->_progress->removeListener($this);
  83.                          $this->_progress->setString("");       // hide % string
  84.                      }}
  85.                  $this->_progress->display();
  86.                  
  87.                  if ($this->_progress->getPercentComplete(== 1{
  88.                      if ($this->_progress->isIndeterminate()) {
  89.                          $this->_progress->setValue(0);
  90.                      }} else {
  91.                      $this->_progress->incValue();
  92.                  }
  93.                  break;
  94.              default:
  95.             }}}
  96.  
  97.     function getCurrent()
  98.     {
  99.         return $this->_current;
  100.     }
  101.  
  102.     function getMessage()
  103.     {
  104.         $c $this->getCurrent();
  105.         $s = "completed $c out of 416";
  106.  
  107.         if (function_exists('ob_get_clean')) {
  108.             $status  ob_get_clean();      // use for PHP 4.3+
  109.         else {
  110.             $status  ob_get_contents();   // use for PHP 4.2+
  111.             ob_end_clean();
  112.         }
  113.         $status '<script type="text/javascript">self.setStatus("'.$s.'"); </script>';
  114.         echo $status;
  115.         ob_start();
  116.         
  117.         if ($c >= 240 {
  118.             return $s;
  119.         else {
  120.             return null;
  121.         }}
  122.  
  123.     function isDone()
  124.     {
  125.         return ( ($this->_progress->getPercentComplete(== 1&&
  126.                  ($this->_progress->isIndeterminate(== false) );
  127.     }
  128.  
  129.  
  130.     function isStarted()
  131.     {
  132.         $action $this->_form->getSubmitValues();
  133.  
  134.         if (isset($action['start'])) {
  135.             return true;
  136.         }
  137.  
  138.         return false;
  139.     }
  140.  
  141.     function run()
  142.     {
  143.         if ($this->isStarted()) {
  144.             $this->_progress->setIndeterminate(true);
  145.             $this->_progress->incValue();
  146.             
  147.         else {
  148.             $abort $this->isCanceled();
  149.         }}}
  150.  
  151. $task = new Task();
  152.  
  153. ?>
  154. <!DOCTYPE html
  155.     PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  156.     "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  157.  
  158. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
  159. <head>
  160. <title>Indeterminate Mode Progress example</title>
  161. <style type="text/css">
  162. <!--
  163. <?php echo $task->getStyle()?>
  164.  
  165. body {
  166.     background-color: #444444;
  167.     color: #EEEEEE;
  168.     font-family: Verdana, Arial;
  169. }
  170.  
  171. a:visited, a:active, a:link {
  172.     color: yellow;
  173. }
  174. // -->
  175. </style>
  176. <script type="text/javascript">
  177. <!--
  178. <?php echo $task->getScript()?>
  179.  
  180. function setStatus(pString)
  181. {
  182.         if (isDom)
  183.             prog = document.getElementById('status');
  184.         if (isIE)
  185.             prog = document.all['status'];
  186.         if (isNS4)
  187.             prog = document.layers['status'];
  188.     if (prog != null) 
  189.         prog.innerHTML = pString;
  190. }
  191. //-->
  192. </script>
  193. </head>
  194. <body>
  195.  
  196. <?php 
  197. echo $task->toHtml()
  198.  
  199. $task->run();
  200. ?>
  201.  
  202. </body>
  203. </html>

Prev Up Next
Using Progress Monitor Expert Guide setProgressAttributes Manual

Documentation generated on Mon, 11 Mar 2019 10:15:06 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.