jsProgressBarHandler.js.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. /*****************************************************************
  2. *
  3. * jsProgressBarHandler 0.3.3 - by Bramus! - http://www.bram.us/
  4. *
  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
  23. * ADD: Config options
  24. * v 0.1 - 2007.08.02 - initial release
  25. *
  26. * @see http://www.barenakedapp.com/the-design/displaying-percentages on how to create a progressBar Background Image!
  27. *
  28. * Licensed under the Creative Commons Attribution 2.5 License - http://creativecommons.org/licenses/by/2.5/
  29. *
  30. *****************************************************************/
  31. // mPDF - see edit near end of script
  32. /**
  33. * CONFIG
  34. * -------------------------------------------------------------
  35. */
  36. // Should jsProgressBarHandler hook itself to all span.progressBar elements? - default : true
  37. var autoHook = true;
  38. // Default Options
  39. var defaultOptions = {
  40. animate : false, // Animate the progress? - default: true
  41. showText : false, // show text with percentage in next to the progressbar? - default : true
  42. width : 120, // Width of the progressbar - don't forget to adjust your image too!!!
  43. height : 12, // Height of the progressbar - don't forget to adjust your image too!!!
  44. boxImage : '<?php echo _MPDF_URI; ?>progress/progbarback.png', // boxImage : image around the progress bar
  45. barImage : '<?php echo _MPDF_URI; ?>progress/progbar.png', // Image to use in the progressbar. Can be an array of images
  46. onTick : function(pbObj) { return true }
  47. }
  48. /**
  49. * NO NEED TO CHANGE ANYTHING BENEATH THIS LINE
  50. * -------------------------------------------------------------
  51. */
  52. /**
  53. * JS_BRAMUS Object
  54. * -------------------------------------------------------------
  55. */
  56. if (!JS_BRAMUS) { var JS_BRAMUS = new Object(); }
  57. /**
  58. * ProgressBar Class
  59. * -------------------------------------------------------------
  60. */
  61. JS_BRAMUS.jsProgressBar = Class.create();
  62. JS_BRAMUS.jsProgressBar.prototype = {
  63. /**
  64. * Datamembers
  65. * -------------------------------------------------------------
  66. */
  67. el : null, // Element where to render the progressBar in
  68. id : null, // Unique ID of the progressbar
  69. percentage : null, // Percentage of the progressbar
  70. options : null, // The options
  71. initialPos : null, // Initial postion of the background in the progressbar
  72. initialPerc : null, // Initial percentage the progressbar should hold
  73. pxPerPercent : null, // Number of pixels per 1 percent
  74. backIndex : null, // index in the array of background images currently used
  75. numPreloaded : null, // number of images preloaded
  76. running : null, // is this one running (being animated) or not?
  77. queue : false, // queue of percentages to set to
  78. /**
  79. * Constructor
  80. *
  81. * @param HTMLElement el
  82. * @param string id
  83. * @param int percentage
  84. * @return void
  85. * -------------------------------------------------------------
  86. */
  87. initialize : function(el, percentage, options) {
  88. // get the options
  89. this.options = Object.clone(defaultOptions);
  90. Object.extend(this.options, options || {});
  91. // datamembers from arguments
  92. this.el = $(el);
  93. this.id = $(el).id;
  94. this.percentage = 0; // Set to 0 intially, we'll change this later.
  95. this.backIndex = 0; // Set to 0 initially
  96. this.numPreloaded = 0; // Set to 0 initially
  97. this.running = false; // Set to false initially
  98. this.queue = Array(); // Set to empty Array initially
  99. // datamembers which are calculatef
  100. this.imgWidth = this.options.width * 2; // define the width of the image (twice the width of the progressbar)
  101. this.initialPos = this.options.width * (-1); // Initial postion of the background in the progressbar (0% is the middle of our image!)
  102. this.pxPerPercent = this.options.width / 100; // Define how much pixels go into 1%
  103. this.initialPerc = percentage; // Store this, we'll need it later.
  104. // enfore backimage array
  105. if (this.options.barImage.constructor != Array) { // used to be (but doesn't work in Safari): if (this.options.barImage.constructor.toString().indexOf("Array") == -1) {
  106. this.options.barImage = Array(this.options.barImage);
  107. }
  108. // preload Images
  109. this.preloadImages();
  110. },
  111. /**
  112. * Preloads the images needed for the progressbar
  113. *
  114. * @return void
  115. * -------------------------------------------------------------
  116. */
  117. preloadImages : function() {
  118. // loop all barimages
  119. for (i = 0; i < this.options.barImage.length; i++) {
  120. // create new image ref
  121. var newImage = null;
  122. newImage = new Image();
  123. // set onload, onerror and onabort functions
  124. newImage.onload = function() { this.numPreloaded++; }.bind(this);
  125. newImage.onerror = function() { this.numPreloaded++; }.bind(this);
  126. newImage.onabort = function() { this.numPreloaded++; }.bind(this);
  127. // set image source (preload it!)
  128. newImage.src = this.options.barImage[i];
  129. // image is in cache
  130. if (newImage.complete) {
  131. this.numPreloaded++;
  132. }
  133. }
  134. // if not IE, check if they're loaded
  135. if (!Prototype.Browser.IE) {
  136. this.checkPreloadedImages();
  137. // if IE, just init the visuals as it's quite hard to tame all IE's
  138. } else {
  139. this.initVisuals();
  140. }
  141. },
  142. /**
  143. * Check whether all images are preloaded and loads the percentage if so
  144. *
  145. * @return void
  146. * -------------------------------------------------------------
  147. */
  148. checkPreloadedImages : function() {
  149. // all images are loaded, go init the visuals
  150. if (parseInt(this.numPreloaded,10) >= parseInt(this.options.barImage.length,10) ) {
  151. // initVisuals
  152. this.initVisuals();
  153. // not all images are loaded ... wait a little and then retry
  154. } else {
  155. if ( parseInt(this.numPreloaded,10) <= parseInt(this.options.barImage.length,10) ) {
  156. // $(this.el).update(this.id + ' : ' + this.numPreloaded + '/' + this.options.barImage.length);
  157. setTimeout(function() { this.checkPreloadedImages(); }.bind(this), 100);
  158. }
  159. }
  160. },
  161. /**
  162. * Intializes the visual output and sets the percentage
  163. *
  164. * @return void
  165. * -------------------------------------------------------------
  166. */
  167. initVisuals : function () {
  168. // create the visual aspect of the progressBar
  169. $(this.el).update(
  170. '<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" />' +
  171. ((this.options.showText == true)?'<span id="' + this.id + '_percentText" class="percentText">0%</span>':''));
  172. // set the percentage
  173. this.setPercentage(this.initialPerc);
  174. },
  175. /**
  176. * Sets the percentage of the progressbar
  177. *
  178. * @param string targetPercentage
  179. * @param boolen clearQueue
  180. * @return void
  181. * -------------------------------------------------------------
  182. */
  183. setPercentage : function(targetPercentage, clearQueue) {
  184. // if clearQueue is set, empty the queue and then set the percentage
  185. if (clearQueue) {
  186. this.percentage = (this.queue.length != 0) ? this.queue[0] : targetPercentage;
  187. this.timer = null;
  188. this.queue = [];
  189. setTimeout(function() { this.setPercentage(targetPercentage); }.bind(this), 10);
  190. // no clearQueue defined, set the percentage
  191. } else {
  192. // add the percentage on the queue
  193. this.queue.push(targetPercentage);
  194. // process the queue (if not running already)
  195. if (this.running == false) {
  196. this.processQueue();
  197. }
  198. }
  199. },
  200. /**
  201. * Processes the queue
  202. *
  203. * @return void
  204. * -------------------------------------------------------------
  205. */
  206. processQueue : function() {
  207. // stuff on queue?
  208. if (this.queue.length > 0) {
  209. // tell the world that we're busy
  210. this.running = true;
  211. // process the entry
  212. this.processQueueEntry(this.queue[0]);
  213. // no stuff on queue
  214. } else {
  215. // return;
  216. return;
  217. }
  218. },
  219. /**
  220. * Processes an entry from the queue (viz. animates it)
  221. *
  222. * @param string targetPercentage
  223. * @return void
  224. * -------------------------------------------------------------
  225. */
  226. processQueueEntry : function(targetPercentage) {
  227. // get the current percentage
  228. var curPercentage = parseInt(this.percentage,10);
  229. // define the new percentage
  230. if ((targetPercentage.toString().substring(0,1) == "+") || (targetPercentage.toString().substring(0,1) == "-")) {
  231. targetPercentage = curPercentage + parseInt(targetPercentage);
  232. }
  233. // min and max percentages
  234. if (targetPercentage < 0) targetPercentage = 0;
  235. if (targetPercentage > 100) targetPercentage = 100;
  236. // if we don't need to animate, just change the background position right now and return
  237. if (this.options.animate == false) {
  238. // remove the entry from the queue
  239. this.queue.splice(0,1); // @see: http://www.bram.us/projects/js_bramus/jsprogressbarhandler/#comment-174878
  240. // Change the background position (and update this.percentage)
  241. this._setBgPosition(targetPercentage);
  242. // call onTick
  243. if (!this.options.onTick(this)) {
  244. return;
  245. }
  246. // we're not running anymore
  247. this.running = false;
  248. // continue processing the queue
  249. this.processQueue();
  250. // we're done!
  251. return;
  252. }
  253. // define if we need to add/subtract something to the current percentage in order to reach the target percentage
  254. if (targetPercentage != curPercentage) {
  255. if (curPercentage < targetPercentage) {
  256. newPercentage = curPercentage + 1;
  257. } else {
  258. newPercentage = curPercentage - 1;
  259. }
  260. callTick = true;
  261. } else {
  262. newPercentage = curPercentage;
  263. callTick = false;
  264. }
  265. // Change the background position (and update this.percentage)
  266. this._setBgPosition(newPercentage);
  267. // call onTick
  268. if (callTick && !this.options.onTick(this)) {
  269. return;
  270. }
  271. // Percentage not reached yet : continue processing entry
  272. if (curPercentage != newPercentage) {
  273. this.timer = setTimeout(function() { this.processQueueEntry(targetPercentage); }.bind(this), 10);
  274. // Percentage reached!
  275. } else {
  276. // remove the entry from the queue
  277. this.queue.splice(0,1);
  278. // we're not running anymore
  279. this.running = false;
  280. // unset timer
  281. this.timer = null;
  282. // process the rest of the queue
  283. this.processQueue();
  284. // we're done!
  285. return;
  286. }
  287. },
  288. /**
  289. * Gets the percentage of the progressbar
  290. *
  291. * @return int
  292. */
  293. getPercentage : function(id) {
  294. return this.percentage;
  295. },
  296. /**
  297. * Set the background position
  298. *
  299. * @param int percentage
  300. */
  301. _setBgPosition : function(percentage) {
  302. // adjust the background position
  303. $(this.id + "_percentImage").style.backgroundPosition = (this.initialPos + (percentage * this.pxPerPercent)) + "px 50%";
  304. // adjust the background image and backIndex
  305. var newBackIndex = Math.floor((percentage-1) / (100/this.options.barImage.length));
  306. if ((newBackIndex != this.backIndex) && (this.options.barImage[newBackIndex] != undefined)) {
  307. $(this.id + "_percentImage").style.backgroundImage = "url(" + this.options.barImage[newBackIndex] + ")";
  308. }
  309. this.backIndex = newBackIndex;
  310. // Adjust the alt & title of the image
  311. $(this.id + "_percentImage").alt = percentage + "%";
  312. $(this.id + "_percentImage").title = percentage + "%";
  313. // Update the text
  314. if (this.options.showText == true) {
  315. $(this.id + "_percentText").update("" + percentage + "%");
  316. }
  317. // adjust datamember to stock the percentage
  318. this.percentage = percentage;
  319. }
  320. }
  321. /**
  322. * ProgressHandlerBar Class - automatically create ProgressBar instances
  323. * -------------------------------------------------------------
  324. */
  325. JS_BRAMUS.jsProgressBarHandler = Class.create();
  326. JS_BRAMUS.jsProgressBarHandler.prototype = {
  327. /**
  328. * Datamembers
  329. * -------------------------------------------------------------
  330. */
  331. pbArray : new Array(), // Array of progressBars
  332. /**
  333. * Constructor
  334. *
  335. * @return void
  336. * -------------------------------------------------------------
  337. */
  338. initialize : function() {
  339. // get all span.progressBar elements
  340. $$('span.progressBar').each(function(el) {
  341. // create a progressBar for each element
  342. this.pbArray[el.id] = new JS_BRAMUS.jsProgressBar(el, parseInt(el.innerHTML.replace("%","")));
  343. }.bind(this));
  344. },
  345. /**
  346. * Set the percentage of a progressbar
  347. *
  348. * @param string el
  349. * @param string percentage
  350. * @return void
  351. * -------------------------------------------------------------
  352. */
  353. setPercentage : function(el, percentage, clearQueue) {
  354. this.pbArray[el].setPercentage(percentage, clearQueue);
  355. },
  356. /**
  357. * Get the percentage of a progressbar
  358. *
  359. * @param string el
  360. * @return int percentage
  361. * -------------------------------------------------------------
  362. */
  363. getPercentage : function(el) {
  364. return this.pbArray[el].getPercentage();
  365. }
  366. }
  367. /**
  368. * ProgressHandlerBar Class - hook me or not?
  369. * -------------------------------------------------------------
  370. */
  371. if (autoHook == true) {
  372. function initProgressBarHandler() { myJsProgressBarHandler = new JS_BRAMUS.jsProgressBarHandler(); }
  373. //document.observe('dom:loaded', initProgressBarHandler, false);
  374. initProgressBarHandler(); // mPDF edit to show immediately before loaded
  375. }