1
/*****************************************************************
3
* jsProgressBarHandler 0.3.3 - by Bramus! - http://www.bram.us/
5
* v 0.3.3 - 2008.11.10 - UPD: fixed IE compatibility issue (thanks Kevin - Sep 19 2008 / 6pm)
6
* - UPD: setPercentage now parses the targetPercentage to an Integer to avoid infinite loop (thanks Jack - Sep 07 2008 / 9pm)
7
* - UPD: Moved from Event.Observe(window, 'load', fn) to document.observe('dom:loaded', fn) in order to force people to use an up to date Prototype release.
8
* - UPD: setPercentage now takes an overrideQueue param. If set the current queue is cleared.
9
* - ADD: Added onTick callback event which gets called when the percentage is updated.
10
* - ADD: Added stable (as in "non-crashing") versions of the additions which first surfaced in the (unreleased) 0.3.2 release
11
* Preloading support partially implemented in IE as all versions (IE6,7&8) are quite hard to tame (one time they work, the next reload they don't anymore)
12
* v 0.3.2 - 2008.04.09 (*UNRELEASED*)
13
* - ADD: implemented preloading of images to avoid slight flicker when switching images (BUGGY!)
14
* - ADD: percentage image now has class percentImage and percentage Text now has class percentText; This allows you to style the output easily.
15
* v 0.3.1 - 2008.02.20 - UPD: fixed queue bug when animate was set to false (thanks Jamie Chong)
16
* - UPD: update Prototype to version 1.6.0.2
17
* v 0.3.0 - 2008.02.01 - ADD: animation queue, prevents from the progressbar getting stuck when multiple calls are made during an animation
18
* - UPD: multiple barImages now work properly in Safari
19
* v 0.2.1 - 2007.12.20 - ADD: option : set boxImage
20
* ADD: option : set barImage (one or more)
21
* ADD: option : showText
22
* v 0.2 - 2007.12.13 - SYS: rewrite in 2 classs including optimisations
24
* v 0.1 - 2007.08.02 - initial release
26
* @see http://www.barenakedapp.com/the-design/displaying-percentages on how to create a progressBar Background Image!
28
* Licensed under the Creative Commons Attribution 2.5 License - http://creativecommons.org/licenses/by/2.5/
30
*****************************************************************/
35
* -------------------------------------------------------------
38
// Should jsProgressBarHandler hook itself to all span.progressBar elements? - default : true
42
var defaultOptions = {
43
animate : false, // Animate the progress? - default: true
44
showText : true, // show text with percentage in next to the progressbar? - default : true
45
width : 120, // Width of the progressbar - don't forget to adjust your image too!!!
46
boxImage : '/grase/images/bramus/percentImage.png', // boxImage : image around the progress bar
47
barImage : '/grase/images/bramus/percentImage_back.png', // Image to use in the progressbar. Can be an array of images too.
48
height : 12, // Height of the progressbar - don't forget to adjust your image too!!!
49
onTick : function(pbObj) { return true }
53
* NO NEED TO CHANGE ANYTHING BENEATH THIS LINE
54
* -------------------------------------------------------------
59
* -------------------------------------------------------------
62
if (!JS_BRAMUS) { var JS_BRAMUS = new Object(); }
67
* -------------------------------------------------------------
70
JS_BRAMUS.jsProgressBar = Class.create();
72
JS_BRAMUS.jsProgressBar.prototype = {
77
* -------------------------------------------------------------
80
el : null, // Element where to render the progressBar in
81
id : null, // Unique ID of the progressbar
82
percentage : null, // Percentage of the progressbar
84
options : null, // The options
86
initialPos : null, // Initial postion of the background in the progressbar
87
initialPerc : null, // Initial percentage the progressbar should hold
88
pxPerPercent : null, // Number of pixels per 1 percent
90
backIndex : null, // index in the array of background images currently used
91
numPreloaded : null, // number of images preloaded
93
running : null, // is this one running (being animated) or not?
95
queue : false, // queue of percentages to set to
101
* @param HTMLElement el
103
* @param int percentage
105
* -------------------------------------------------------------
108
initialize : function(el, percentage, options) {
111
this.options = Object.clone(defaultOptions);
112
Object.extend(this.options, options || {});
114
// datamembers from arguments
117
this.percentage = 0; // Set to 0 intially, we'll change this later.
118
this.backIndex = 0; // Set to 0 initially
119
this.numPreloaded = 0; // Set to 0 initially
120
this.running = false; // Set to false initially
121
this.queue = Array(); // Set to empty Array initially
123
// datamembers which are calculatef
124
this.imgWidth = this.options.width * 2; // define the width of the image (twice the width of the progressbar)
125
this.initialPos = this.options.width * (-1); // Initial postion of the background in the progressbar (0% is the middle of our image!)
126
this.pxPerPercent = this.options.width / 100; // Define how much pixels go into 1%
127
this.initialPerc = percentage; // Store this, we'll need it later.
129
// enfore backimage array
130
if (this.options.barImage.constructor != Array) { // used to be (but doesn't work in Safari): if (this.options.barImage.constructor.toString().indexOf("Array") == -1) {
131
this.options.barImage = Array(this.options.barImage);
135
this.preloadImages();
141
* Preloads the images needed for the progressbar
144
* -------------------------------------------------------------
147
preloadImages : function() {
149
// loop all barimages
150
for (i = 0; i < this.options.barImage.length; i++) {
152
// create new image ref
154
newImage = new Image();
156
// set onload, onerror and onabort functions
157
newImage.onload = function() { this.numPreloaded++; }.bind(this);
158
newImage.onerror = function() { this.numPreloaded++; }.bind(this);
159
newImage.onabort = function() { this.numPreloaded++; }.bind(this);
161
// set image source (preload it!)
162
newImage.src = this.options.barImage[i];
165
if (newImage.complete) {
171
// if not IE, check if they're loaded
172
if (!Prototype.Browser.IE) {
173
this.checkPreloadedImages();
175
// if IE, just init the visuals as it's quite hard to tame all IE's
184
* Check whether all images are preloaded and loads the percentage if so
187
* -------------------------------------------------------------
190
checkPreloadedImages : function() {
192
// all images are loaded, go init the visuals
193
if (parseInt(this.numPreloaded,10) >= parseInt(this.options.barImage.length,10) ) {
198
// not all images are loaded ... wait a little and then retry
201
if ( parseInt(this.numPreloaded,10) <= parseInt(this.options.barImage.length,10) ) {
202
// $(this.el).update(this.id + ' : ' + this.numPreloaded + '/' + this.options.barImage.length);
203
setTimeout(function() { this.checkPreloadedImages(); }.bind(this), 100);
212
* Intializes the visual output and sets the percentage
215
* -------------------------------------------------------------
218
initVisuals : function () {
220
// create the visual aspect of the progressBar
222
'<img id="' + this.id + '_percentImage" src="' + this.options.boxImage + '" alt="0%" style="width: ' + this.options.width + 'px; height: ' + this.options.height + 'px; background-position: ' + this.initialPos + 'px 50%; background-image: url(' + this.options.barImage[this.backIndex] + '); padding: 0; margin: 0;" class="percentImage" />' +
223
((this.options.showText == true)?'<span id="' + this.id + '_percentText" class="percentText">0%</span>':''));
225
// set the percentage
226
this.setPercentage(this.initialPerc);
231
* Sets the percentage of the progressbar
233
* @param string targetPercentage
234
* @param boolen clearQueue
236
* -------------------------------------------------------------
238
setPercentage : function(targetPercentage, clearQueue) {
240
// if clearQueue is set, empty the queue and then set the percentage
243
this.percentage = (this.queue.length != 0) ? this.queue[0] : targetPercentage;
247
setTimeout(function() { this.setPercentage(targetPercentage); }.bind(this), 10);
249
// no clearQueue defined, set the percentage
252
// add the percentage on the queue
253
this.queue.push(targetPercentage);
255
// process the queue (if not running already)
256
if (this.running == false) {
265
* Processes the queue
268
* -------------------------------------------------------------
271
processQueue : function() {
274
if (this.queue.length > 0) {
276
// tell the world that we're busy
280
this.processQueueEntry(this.queue[0]);
294
* Processes an entry from the queue (viz. animates it)
296
* @param string targetPercentage
298
* -------------------------------------------------------------
301
processQueueEntry : function(targetPercentage) {
303
// get the current percentage
304
var curPercentage = parseInt(this.percentage,10);
306
// define the new percentage
307
if ((targetPercentage.toString().substring(0,1) == "+") || (targetPercentage.toString().substring(0,1) == "-")) {
308
targetPercentage = curPercentage + parseInt(targetPercentage);
311
// min and max percentages
312
if (targetPercentage < 0) targetPercentage = 0;
313
if (targetPercentage > 100) targetPercentage = 100;
315
// if we don't need to animate, just change the background position right now and return
316
if (this.options.animate == false) {
318
// remove the entry from the queue
319
this.queue.splice(0,1); // @see: http://www.bram.us/projects/js_bramus/jsprogressbarhandler/#comment-174878
321
// Change the background position (and update this.percentage)
322
this._setBgPosition(targetPercentage);
325
if (!this.options.onTick(this)) {
329
// we're not running anymore
330
this.running = false;
332
// continue processing the queue
339
// define if we need to add/subtract something to the current percentage in order to reach the target percentage
340
if (targetPercentage != curPercentage) {
341
if (curPercentage < targetPercentage) {
342
newPercentage = curPercentage + 1;
344
newPercentage = curPercentage - 1;
348
newPercentage = curPercentage;
352
// Change the background position (and update this.percentage)
353
this._setBgPosition(newPercentage);
356
if (callTick && !this.options.onTick(this)) {
360
// Percentage not reached yet : continue processing entry
361
if (curPercentage != newPercentage) {
363
this.timer = setTimeout(function() { this.processQueueEntry(targetPercentage); }.bind(this), 10);
365
// Percentage reached!
368
// remove the entry from the queue
369
this.queue.splice(0,1);
371
// we're not running anymore
372
this.running = false;
377
// process the rest of the queue
388
* Gets the percentage of the progressbar
392
getPercentage : function(id) {
393
return this.percentage;
398
* Set the background position
400
* @param int percentage
402
_setBgPosition : function(percentage) {
403
// adjust the background position
404
$(this.id + "_percentImage").style.backgroundPosition = (this.initialPos + (percentage * this.pxPerPercent)) + "px 50%";
406
// adjust the background image and backIndex
407
var newBackIndex = Math.floor((percentage-1) / (100/this.options.barImage.length));
409
if ((newBackIndex != this.backIndex) && (this.options.barImage[newBackIndex] != undefined)) {
410
$(this.id + "_percentImage").style.backgroundImage = "url(" + this.options.barImage[newBackIndex] + ")";
413
this.backIndex = newBackIndex;
415
// Adjust the alt & title of the image
416
$(this.id + "_percentImage").alt = percentage + "%";
417
$(this.id + "_percentImage").title = percentage + "%";
420
if (this.options.showText == true) {
421
$(this.id + "_percentText").update("" + percentage + "%");
424
// adjust datamember to stock the percentage
425
this.percentage = percentage;
431
* ProgressHandlerBar Class - automatically create ProgressBar instances
432
* -------------------------------------------------------------
435
JS_BRAMUS.jsProgressBarHandler = Class.create();
438
JS_BRAMUS.jsProgressBarHandler.prototype = {
443
* -------------------------------------------------------------
446
pbArray : new Array(), // Array of progressBars
453
* -------------------------------------------------------------
456
initialize : function() {
458
// get all span.progressBar elements
459
$$('span.progressBar').each(function(el) {
461
// create a progressBar for each element
462
this.pbArray[el.id] = new JS_BRAMUS.jsProgressBar(el, parseInt(el.innerHTML.replace("%","")));
469
* Set the percentage of a progressbar
472
* @param string percentage
474
* -------------------------------------------------------------
476
setPercentage : function(el, percentage, clearQueue) {
477
this.pbArray[el].setPercentage(percentage, clearQueue);
482
* Get the percentage of a progressbar
485
* @return int percentage
486
* -------------------------------------------------------------
488
getPercentage : function(el) {
489
return this.pbArray[el].getPercentage();
496
* ProgressHandlerBar Class - hook me or not?
497
* -------------------------------------------------------------
500
if (autoHook == true) {
501
function initProgressBarHandler() { myJsProgressBarHandler = new JS_BRAMUS.jsProgressBarHandler(); }
502
document.observe('dom:loaded', initProgressBarHandler, false);