David Walsh Blog

Animated Progress Bars Using MooTools: dwProgressBar

I love progress bars. It’s important that I know roughly what percentage of a task is complete. I’ve created a highly customizable MooTools progress bar class that animates to the desired percentage.

The Moo-Generated XHTML


	<div id="this.options.boxID">
		<div id="this.options.percentageID"></div>
	</div>
	<div id="this.options.displayID">{x}%</div>

This DIV structure is extremely simple and can be controlled completely by CSS.

The CSS


	/* these selector names are based on what you provide to the class */
	
	/* example 1 */
	#box			{ border:1px solid #ccc; width:200px; height:20px; }
	#perc			{ background:#ccc; height:20px; }
	
	/* example 2 */
	#box2			{ background:url(progress-bar-back.gif) right center no-repeat; width:200px; height:20px; float:left; }
	#perc2			{ background:url(progress-bar.gif) right center no-repeat; height:20px; }
	#text			{ font-family:tahoma, arial, sans-serif; font-size:11px; color:#000; float:left; padding:3px 0 0 10px; }
	

You’ll declare styles for the three generated XHTML elements. You’ll like use background colors and background images. You will also want to define a width value for the outside box.

The MooTools JavaScript: dwProgressBar


//class is in
var dwProgressBar = new Class({
	
	//implements
	Implements: [Options],

	//options
	options: {
		container: $$('body')[0],
		boxID:'',
		percentageID:'',
		displayID:'',
		startPercentage: 0,
		displayText: false,
		speed:10
	},
	
	//initialization
	initialize: function(options) {
		//set options
		this.setOptions(options);
		//create elements
		this.createElements();
	},
	
	//creates the box and percentage elements
	createElements: function() {
		var box = new Element('div', { id:this.options.boxID });
		var perc = new Element('div', { id:this.options.percentageID, 'style':'width:0px;' });
		perc.inject(box);
		box.inject(this.options.container);
		if(this.options.displayText) { 
			var text = new Element('div', { id:this.options.displayID });
			text.inject(this.options.container);
		}
		this.set(this.options.startPercentage);
	},
	
	//calculates width in pixels from percentage
	calculate: function(percentage) {
		return ($(this.options.boxID).getStyle('width').replace('px','') * (percentage / 100)).toInt();
	},
	
	//animates the change in percentage
	animate: function(to) {
		$(this.options.percentageID).set('morph', { duration: this.options.speed, link:'cancel' }).morph({width:this.calculate(to.toInt())});
		if(this.options.displayText) { 
			$(this.options.displayID).set('text', to.toInt() + '%'); 
		}
	},
	
	//sets the percentage from its current state to desired percentage
	set: function(to) {
		this.animate(to);
	}
	
});

The class accepts the following options:

 

MooTools Usage


//once the DOM is ready
window.addEvent('domready', function() {
	
	/* create the progress bar for example 1 */
	pb = new dwProgressBar({
		container: $('put-bar-here'),
		startPercentage: 25,
		speed:1000,
		boxID: 'box',
		percentageID: 'perc'
	});
		
	/* create the progress bar for example 2 */
	pb2 = new dwProgressBar({
		container: $('put-bar-here2'),
		startPercentage: 10,
		speed:1000,
		boxID: 'box2',
		percentageID: 'perc2',
		displayID: 'text',
		displayText: true
	});
	
	/* move the first progress bar to 55% */
	pb.set(55);
	
	/* move the second progress bar to 89% */
	pb2.set(89);
		
});

All you need to do is create an instance of the dwProgressBar and pass your desired options. It’s quick and easy. To move the progress bar, all you need to do is call the “set()” method, passing it the desired percentage.

Practical Uses

You could use this progress bar for:

 

I’ve made the progress bar as flexible as possible by allowing the developer to format each generated DIV using CSS.

Also, please feel free to make suggestions for the class. I may implement them in the future!