Progress Bar (Unbounded)
Progress Bar (Unbounded)
The unbounded progress bar is not tied to any progressive increments. It is basically a "busy" or "in progress" message. It will continue until it is cancelled by another event. If there is no such event, it will continue forever.
Note:
The unbounded progress bar is not keyboard-focusable, so if you want to hear it read by a screen reader, you will need to navigate to it via text navigation (down arrow key in JAWS and NVDA; Alt + right arrow in Narrator; Control + Option + Right arrow in VoiceOver)
Turn on a screen reader to experience this example in action.
Attribute/Option | Description |
---|---|
message | This atrribute/option specifies message for the screen readers. If this option is not provided, a default message is set for the screen readers. |
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. |
indicator_color_gradient | This atrribute/option sets the progress indicator as a color gradient of your choice. If this option is not provided, a default color gradient is set. |
Data Processing
HTML Source Code
<table class="data">
<tr>
<th width="150px" >Attribute/Option</th>
<th>Description</th>
</tr>
<tr>
<td>message</td>
<td>This atrribute/option specifies message for the screen readers.
If this option is not provided, a default message is set for the screen readers.
</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>
<tr>
<td> indicator_color_gradient </td>
<td>This atrribute/option sets the progress indicator as a color gradient of your choice.
If this option is not provided, a default color gradient is set.
</td>
</tr>
</table>
<h2 id="task_label">
Data Processing
</h2>
<div id="progressbar-container"></div>
<p>
<button class="button" id="start-progressbar">
Start
</button>
<button class="button" id="stop-progressbar">
Stop
</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.",
"msgProcessing": "processing in progress...",
"msgPleaseWait": "please wait...",
"msgProcessingCompleted": "processing completed.",
}
var progressbar;
window.addEventListener('load', function () {
var div = document.getElementById("progressbar-container");
var options = [];
//options["indicator_color_gradient"] = "linear-gradient(to right, #c12800 0, rgba(255, 255, 255, 0) 50%, #c12800 100%)";
options["height"] = 10;
progressbar = new ProgressbarUnbounded(div, options);
var startButton = document.getElementById("start-progressbar");
startButton.addEventListener("click", startProgressbar);
var stopButton = document.getElementById("stop-progressbar");
stopButton.addEventListener("click", stopProgressbar);
});
var intervalId = null;
var progressValue = 10;
function startProgressbar(event)
{
progressbar.show();
}
function stopProgressbar()
{
progressbar .hide(langText["msgProcessingCompleted"]);
}
class ProgressbarUnbounded {
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 = [];
this.processingMessage = langText["msgProcessing"];
if(typeof options["message"] === "string")
this.processingMessage = options["message"];
var height = "30";
if(typeof options["height"] === "number")
height = options["height"];
var padding = "5";
if(typeof options["padding"] === "number")
padding = options["padding"];
var indicatorColorGradient = "linear-gradient(to right, #006cc1 0, rgba(255, 255, 255, 0) 50%, #006cc1 100%)";
if(typeof options["indicator_color_gradient"] === "string")
indicatorColorGradient = options["indicator_color_gradient"];
var progressbar = document.createElement("progressbar");
progressbar.classList.add("progressbara");
progressbar.style.width = "calc(100%-"+padding+"px)";
progressbar.style.height = height+"px";
progressbar.style.display = "none";
progressbar.style.padding = padding + "px";
this.parentNode.appendChild(progressbar);
progressbar.style.backgroundImage = indicatorColorGradient;
progressbar.style.animation = "20s linear infinite move";
this.progressbar = progressbar;
var notifyElement = document.createElement("p");
notifyElement.setAttribute("aria-live", "polite");
notifyElement.classList.add("visually-hidden");
this.parentNode.appendChild(notifyElement);
this.notifyElement = notifyElement;
}
show()
{
this.progressbar.style.display = "block";
var self = this;
var announceMessage = true;
if(typeof this.intervalId != "undefined") clearInterval(this.intervalId);
this.intervalId = setInterval(function(){
if(announceMessage)
self.announce(self.processingMessage,120,2000,"show");
else
self.announce(langText["msgPleaseWait"],120,1500,"show");
announceMessage = !announceMessage;
}, 2000);
}
hide(message)
{
this.progressbar.style.display = "none";
if(typeof this.intervalId != "undefined") clearInterval(this.intervalId);
if(typeof message === "string")
this.announce(message,0,2000,"hide");
}
announce(message, initialDelay, msgTime, scope)
{
var self=this;
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 = message;
}, initialDelay);
}
else
this.notifyElement.innerHTML = message;
setTimeout(function() {
self.notifyElement.innerHTML ="";
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;
}
@keyframes move {
0% {
background-position: 0 0
}
100% {
background-position: -10000px 0
}
}