Ever needed to show something on-screen as a percentage / bar in javascript? Yes, it has been done a countless number of times before. Sometimes, even in mootools. But we like adding our own functions to the dci_core.js mini library whenever possible. So … here is a very easy and good-looking way of doing it (well, subject of what background images you can come up with, of course). The idea is simple: have a container element with a background image that is offset to outside the element’s boundaries via the background-position CSS property. As the percentage is being calculated, the background image is bring brought into view.
Our progress images look like this:
200px wide, so each percent is represented by 2px, something that is reflected in the script below. Here is the target element, styled as per our CSS:
Some more examples of various options for the progress bar, settings are contained within the actual elements:
4 of 5, ‘completed’, no tween
14 of 80, ‘Questions’, cubic tween
Get current percent from element’s storage
Here’s the relevant CSS:
.progress { width: 200px; border: 1px solid #000; background-color: #d81e05; background-image: url(/gallery/img/progress.gif); background-repeat: no-repeat; background-position: -210px 0; height: 16px; line-height: 1; color: #F4F4F4; font-weight: bold; margin-bottom: 4px; } .progress2 { width: 202px; border: 1px solid #000; background-color: #555; background-image: url(/images/progressbar-orange.gif); background-repeat: no-repeat; background-position: -210px 0px; height: 21px; color: #000; font-weight: bold; margin-left: 1px; }
The actual div and html:
<div class="progress" id="someid"></div> Some more examples of various options for the progress bar, settings are contained within the actual elements: <a href="#" class="barbar" data-data="{count:23,total:26,message:'loaded...',className:'progress2'}">23 of 26, "images loaded..." with cubic tween, class: progress2</a> <a href="#" class="barbar" data-data="{count:4,total:5,message:'completed',tween:false}">4 of 5, 'completed', no tween</a> <a href="#" class="barbar" data-data="{count:14,total:80,message:'Questions'}">14 of 80, 'Questions', cubic tween</a>
Here’s how we extend the element in mootools and call the methods we need:
Element.implement({ showProgress: function(options) { options = $merge({ count: 0, total: 10, message: "", className: "progress", // default css class backgroundPosition: 200, // start pos tween: true // animate or static }, options); // calculate % of progress var percent = options.total / 100, donePercent = (options.count / percent).round(), BGoffset = options.backgroundPosition - (donePercent*2).round(); // set inline message this.set({ styles: { "background-position": "-" + options.backgroundPosition + "px" }, html: " " + options.count + " of " + options.total + " " + options.message + " ("+donePercent+"%)", "class": options.className }); if (options.tween) new Fx.Tween(this, { duration: 500, transition: Fx.Transitions.Cubic.easeIn }).start("background-position", "-" + BGoffset); else this.setStyle("background-position", "-" + BGoffset + "px"); this.store("percent", donePercent); // element storage, use element.retrieve("data-percent") to get current progress. return this; } }); // end extending elements // apply initial state $("someid").showProgress({count:3,total:10}); // bind the links to change the bar graph to real time data. $$("a.barbar").addEvents({ click: function(e) { new Event(e).stop(); $("someid").showProgress(JSON.decode(this.get("data-data"))); } }); // show / read percent from element storage $("fetchPercent").addEvent("mouseenter", function(e) { this.tooltip("This bar at " + $("someid").retrieve("percent") + "%"); });
That’s it, I hope it helps you. In an ideal world, this could be refactored into a mootools class but who has the time…
_update_ fixed minor bugs and got this working after new skin was applied. working on a class for it with proper events that can be used as a mixin