Progress Bar (Bounded)

Progress Bar (Bounded)

A bounded progress bar helps users understand how much time is remaining in a process. Both sighted and blind users should be informed of the intervals with the progress bar.



Turn on a screen reader to experience this example in action.

Attribute/Option Description
background_color This atrribute/option sets the background color of the progressbar. By default, it is set to "aliceblue" color.
indicator_color This atrribute/option sets the progress indicator color. By default, it is set to "blue" color.
indicator_color_gradient This atrribute/option sets the progress indicator as a color gradient of your choice. By default, this atrribute/option is not set.
height This atrribute/option specifies the height of the progressbar widget. By default, it is set to 50px.
padding This atrribute/option specifies the padding to be used for the progressbar widget. By default, it is set to 5px.

Task Completion

HTML Source Code

<table class="data">
    <tr>
        <th width="150px" >Attribute/Option</th>
        <th>Description</th>
    </tr>
    <tr>
        <td>background_color</td>
        <td>This atrribute/option sets the background color of the progressbar. 
            By default, it is set to "aliceblue" color.
        </td>
        </tr>
    <tr>
        <td>indicator_color</td>
        <td>This atrribute/option sets the progress indicator color. 
            By default, it is set to "blue" color.
        </td>
    </tr>
    <tr>
        <td>indicator_color_gradient</td>
        <td>This atrribute/option sets the progress indicator as a color gradient of your choice. 
            By default, this atrribute/option is not set.
        </td>
    </tr>
    <tr>
        <td>height</td>
        <td>This atrribute/option specifies the height of the progressbar widget.
            By default, it is set to 50px. 
        </td>
    </tr>
    <tr>
        <td>padding</td>
        <td>This atrribute/option specifies the padding to be used for the progressbar widget.
            By default, it is set to 5px. 
        </td>
    </tr>
</table>
<br/>
<h2 id="task_label">
    Task Completion 
</h2>
<div id="progressbar-container"></div>
<p>
    <button class="deque-button" id="start-progressbar">
        Start
    </button>
    <button class="deque-button" id="reset-progressbar">
        Reset
    </button>
</p>

JavaScript Source Code

//Language object to be modified as per the language
var langText = {
    "errorNodeNotObject": "Node provided is not a DOM object.",
    "errorNodeNotDivObject": "Node provided is not a DIV HTML object.",
    "errorValueGreaterThanMax": "Value passed is greater than the maximum value allowed.",
    "errorValueLessThanMin": "Value passed is less than the minimum value allowed.",

}
var progressbar;
window.addEventListener('load', function () {
    var options = [];
    var div = document.getElementById("progressbar-container");
    //options["background_color"] = "#ff000017";
    //options["indicator_color"] = "darkred";
    //options["indicator_color_gradient"] = "linear-gradient(180deg, #2af598 0%, #009efd 100%)";
    //options["height"] = 20;
    //options["padding"] = 10;
    
    progressbar = new Progressbar(div, options);
    var startButton = document.getElementById("start-progressbar");
    startButton.addEventListener("click", startStopProgressbar);
    var resetButton = document.getElementById("reset-progressbar");
    resetButton.addEventListener("click", resetProgressbar);
    
});

var intervalId = null;
var progressValue = 10;
function startStopProgressbar(event)
{
    var button = document.getElementById("start-progressbar");
    var isAriaPressed = toggleButton(button);
    if(isAriaPressed)
    {
        
        button.innerHTML = "Start";
        button.classList.remove("pressed");
        if(intervalId) clearInterval(intervalId);  
    }
    else
    {
        
        var simulateProgress = function ()
        {
            progressbar.setProgressValue(progressValue);
            if( progressValue >= 100)
                if(intervalId) clearInterval(intervalId); 
            progressValue += 10;
        };
        if(progressValue < 100 )
            intervalId = setInterval(simulateProgress, 1500);
        button.innerHTML = "Stop";
        button.classList.add("pressed");
    }    
}

function toggleButton(button)
{
    var isAriaPressed = button.getAttribute('aria-pressed') === 'true';
    button.setAttribute('aria-pressed', isAriaPressed ? 'false' : 'true');
    return isAriaPressed;
}

function resetProgressbar()
{
    if(intervalId) clearInterval(intervalId);  
    var button = document.getElementById("start-progressbar");
    progressbar.setProgressValue(5);
    progressValue = 10;
    var isAriaPressed = button.getAttribute('aria-pressed') === 'true';
    if(isAriaPressed)
    {
        toggleButton(button);
        button.innerHTML = "Start";
        button.classList.remove("pressed");         
    }
}

class Progressbar {
constructor(node, options) {
  // Check whether node is a DOM element
  if (typeof node !== 'object') {
      console.log(langText["errorNodeNotObject"]);
      return;
  }
  if( (typeof node.nodeName === "undefined") || ( node.nodeName.toLowerCase() !== "div" ))
  {
      console.log(langText["errorNodeNotDivObject"]);
      return;
  }
  
  this.parentNode = node;
  if ( (typeof options == "undefined") || (!Array.isArray(options)) ) options = [];
  var indicatorColor = "blue";
  if(typeof options["indicator_color"] === "string")
      indicatorColor = options["indicator_color"];
   var indicatorColorGradient = "";
   if(typeof options["indicator_color_gradient"] === "string")
      indicatorColorGradient = options["indicator_color_gradient"];
  var backgroundColor = "aliceblue";
  if(typeof options["background_color"] === "string")
      backgroundColor = options["background_color"];
    
  var height = "50";
  if(typeof options["height"] === "number")
      height = options["height"];
    var padding = "5";
  if(typeof options["padding"] === "number")
      padding = options["padding"];
      
  
   var progressbar = document.createElement("progressbar");
   progressbar.classList.add("progressbara");
   progressbar.style.width = "calc(100%-10px)";
   progressbar.style.height = height+"px";
   progressbar.style.display = "block";
   progressbar.style.padding = padding + "px";
   progressbar.style.backgroundColor = backgroundColor;
   
   progressbar.setAttribute("min",0);
   progressbar.setAttribute("max",100);
   progressbar.setAttribute("value",5);
      
   this.parentNode.appendChild(progressbar);
   var indicator = document.createElement("rect");
   indicator.style.height = "100%";
   indicator.style.display = "inline-block";
   indicator.style.backgroundColor = indicatorColor;
   if(indicatorColorGradient != "")
        indicator.style.backgroundImage = indicatorColorGradient;
   progressbar.appendChild(indicator);
   this.indicator = indicator;
   this.progressbar = progressbar;
   
   var notifyElement = document.createElement("p");
    notifyElement.setAttribute("aria-live", "assertive");
    notifyElement.classList.add("visually-hidden");
    this.parentNode.appendChild(notifyElement);
    this.notifyElement = notifyElement;
    this.updateProgress();
    
  
}

updateProgress()
{
    var value = this.progressbar.getAttribute("value");
    var max = this.progressbar.getAttribute("max");
    var min = this.progressbar.getAttribute("min");
    var currentProgress = value *100 /( max - min);
    this.indicator.style.width = currentProgress + "%";
    this.announce(currentProgress+"%", 60  , 2000, "updateProgress");
   
}
setProgressValue(value)
{
    var max = this.progressbar.getAttribute("max");
    var min = this.progressbar.getAttribute("min");
    if( (value > max) || ( value < min))
    {
        if( value > max )
            console.log(langText["errorValueGreaterThanMax"]);
        if( value < min )
            console.log(langText["rrorValueLessThanMin"]);
        return;   
    }
    this.progressbar.setAttribute("value", value);
    this.updateProgress();
}

announce(message, initialDelay, msgTime, scope)
{
    var self=this;    
    this.message = message;
    if(typeof scope == "undefined") scope = "unknown";
    if(typeof this.scopeIds == "undefined" ) this.scopeIds = [];
    if( typeof this.scopeIds[scope] == "number")
    {
        clearTimeout(this.scopeIds[scope]);
        this.scopeIds[scope] = null;
    }
            
    if (initialDelay > 1)
    {
        this.scopeIds[scope] = setTimeout(function() {
            self.notifyElement.innerHTML = self.message;
        }, initialDelay);    
    }    
    else
        this.notifyElement.innerHTML = this.message;
    
    
    setTimeout(function() {
        self.notifyElement.innerHTML ="";
        this.message = "";
        self.scopeIds[scope] = null;
    }, msgTime);

}

}  

CSS Source Code

.button { 
    padding: 5px 10px; 
    display: inline-block; 
    width: 150px;
    border: 2px solid gray;
    border-left: 1px solid lightgray;
    border-top: 1px solid lightgray;
    border-right: 2px solid gray;
    border-bottom: 2px solid gray;
    margin: 2px;
    background-color: #e8e5e5;
}

.pressed {
    border-left: 2px solid gray;
    border-top: 2px solid gray;
    border-right: 1px solid lightgray;
    border-bottom: 1px solid lightgray;
    
}

button {     padding: 5px 10px; width: 170px;}

.button:hover{
    outline: 2px solid blue;
}

.button:focus{
    margin: 2px;
    outline: 2px solid blue;
}  
 
.visually-hidden{
        border: 0;
        clip: rect(0 0 0 0);
        height: 1px;
        margin: -1px;
        overflow: hidden;
        padding: 0;
        position: absolute;
        white-space: nowrap;
        width: 1px;
}
.progressbar {
    width: calc(100% -10);
height: 50px;
display: block;
background-color: aliceblue;
padding: 5px;
}   


/*stand alone page styles*/
table td, table th {
    border: 1px solid black;
    padding: 3px;
}
table {     border-collapse: collapse;  margin: 20px;}
th {
    display: table-cell;
    vertical-align: inherit;
    font-weight: bold;
    text-align: -internal-center;
    unicode-bidi: isolate;
}

Copy and Paste Full Page Example