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:



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>
You may notice the element has a CSS dropshadow applied to it, unless you are in IE. If you are interested how this works, have a look at our mooShadow element method for absolutely positioned elements (hence the need to setStyle to absolute and back to relative afterwards, something of an issue with IE)

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…