Latest: Genstatic, my first sip of coffee

Content with Style

Web Technique

jQuery clickable percentage bars

by Pascal Opitz on December 3 2010, 11:50

Just a little script I have been coding up to deal with input fields that represent a percentage value. See the demo or get the code on github. Enjoy.

Update: I modified the code and moved it from a gist into a public repo on github.


(function(){
    var _self = this;
    
    function render(conf, val) {
        var elems = this;
        
        if(conf == 'destroy') {
            $(elems).each(function() {
                $(this).show();

                if(this.percentage) {
                    $(this.percentage).remove();
                }
            })
            return elems;
        }

        var defaults = {
            width: 200,
            height: 15,
            border: '1px solid #000000',
            color: '#cc0000',
            background: '#ffffff',
            clickable: true,
            classname: 'percentage',
            display: 'inline-block'
        };
        
        if(conf == undefined) {
            conf = defaults;
        } else {
            for(i in defaults) {
                if(conf[i] == undefined) {
                    conf[i] = defaults[i];
                }
            }
        }
        
        function getLeft(newVal) {
            return Math.floor((conf.width * -1) + (conf.width / 100 * newVal))
        }
        
        function updateElem(elem, val) {
            if($(elem).is('textarea,input,select')) {
                $(elem)
                    .attr('value', val)
                    .val(val)
                    .attr('title', val + '%')
                    ;
            } else {
                $(elem)
                    .text(val + '%')
                    ;
            }
        }

        if(conf == 'set') {
            $(elems).each(function() {
                var elem = this;
                conf = elem.percentage_conf;
                updateElem(elem, val);
                $(elem.percentage).find('div').css('left', getLeft(val));
            });
            return elems;
        }

        $(elems).each(function() {
            var elem = this;
            var bar = $('<div></div>');
            var inner = $('<div></div>');
            
            var percent;
            var hasValue;
            
            if($(elem).is('textarea,input,select')) {
                percent = $(elem).val();
                hasValue = true;
            } else {
                percent = parseInt($(elem).text().replace('%', ''));
                hasValue = false;
            }
            
            function handleClick(e) {
                var p = $(this).offset();
                var percent = Math.ceil((e.clientX - p.left) / (conf.width / 100));
                
                updateElem(elem, percent);
                $(elem).trigger('clickupdate');
                
                $(inner)
                    .css('left', getLeft(percent))
                    ;
                
                return false;
            }
            
            $(bar)
                .attr('title', percent + '%')
                .css('display', conf.display)
                .css('border', conf.border)
                .css('background', conf.background)
                .css('position', 'relative')
                .css('overflow', 'hidden')
                .css('width',  conf.width)
                .css('height', conf.height)
                ;
                
            if(conf.clickable) {
                $(bar).click(handleClick);
            }

            if(conf.classname) {
                $(bar).addClass(conf.classname);
            }

            $(inner)
                .css('background', conf.color)
                .css('position', 'absolute')
                .css('top', 0)
                .css('left', getLeft(percent))
                .css('width',  conf.width)
                .css('height', conf.height)
                .appendTo(bar)
                ;
            
            $(elem)
                .hide()
                .after(bar)
                ;
                
            this.percentage = bar;
            this.percentage_conf = conf;
        });
        
        return elems;
    }

    jQuery.fn.percentage = function() {
        render.apply(this, arguments);
    };
})();

Comments


Comments for this article are closed.


If we're already connected on twitter you can join the discussion by replying to this tweet we've made. They will then come up in the comments automatically.
If not, follow us already!