Introducing jCount a JQuery countup plugin with output number formatting

In the history of the interwebs, there is one ‘problem’ that has been solved more times than any other and that is the visitor counter on a web page. This real-time relic of the HTML 1.0 era is the original analytics productand continues it’s reign in the Web 2.0 age through a variety of implementations, most notably jQuery plugins.

You can find some solid examples of modern counters in the wild here and here

I recently had to implement just such a feature for an analytics product I’m working on and ran into one classic problem that twisted my noodle a bit but in the end had a simple solution.

FIrst, I decided to keep the adventure short by employing some sound programming advice from Mark Twain: “amateurs borrow, professionals steal”. So, I looked around for a good pattern or plugin to solve my troubles.

However, nothing takes you back to 1995 faster than doing a google search for javascript counter.

Some of the recent javascript or jquery plugins that are out there are just…dated (I’m being polite because someone slaved over that code and opinions on fashion never hold up anyway).

If you want a mid-90’s style counter, I recommend this one from tinycounter.com – not for it’s functionality, for it’s style!

Anyway, the pattern I decided to go with I found as an answer on stackoverflow.com, posted by Matt Huggins.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
(function($) {

$.fn.countTo = function(options) {
// merge the default plugin settings with the custom options
options = $.extend({}, $.fn.countTo.defaults, options || {});

// how many times to update the value, and how much to increment the value on each update
var loops = Math.ceil(options.speed / options.refreshInterval),
increment = (options.to - options.from) / loops;

return $(this).each(function() {
var _this = this,
loopCount = 0,
value = options.from,
interval = setInterval(updateTimer, options.refreshInterval);

function updateTimer() {
value += increment;
loopCount++;
$(_this).html(value.toFixed(options.decimals));

if (typeof(options.onUpdate) == 'function') {
options.onUpdate.call(_this, value);
}

if (loopCount >= loops) {
clearInterval(interval);
value = options.to;

if (typeof(options.onComplete) == 'function') {
options.onComplete.call(_this, value);
}
}
}

});
};

$.fn.countTo.defaults = {
from: 0, // the number the element should start at
to: 100, // the number the element should end at
speed: 1000, // how long it should take to count between the target numbers
refreshInterval: 100, // how often the element should be updated
decimals: 0, // the number of decimal places to show
onUpdate: null, // callback method for every time the element is updated,
onComplete: null // callback method for when the element finishes updating
};
})(jQuery);

This looks like a solid pattern to my weak javascript eyes (and after a few months of use, it has held up nicely).

One thing that this doesn’t do out of the box is format the numbers using commas.

I wrestled with a few ways to ‘solve this problem’ and a lack of sleep or too much caffeine (or both?) prevented me from seeing a really simple answer. I had already been using a snippet called addCommas (that I believe originates from this blog) but I was executing the addCommas using the countTo() callback.

The result was a jarring visual effect of a) removing the commas, b) counting up to the next new value and c) displaying the commas again.

This behavior (which I thought of as a feature) was quietly scorned by my coworkers for it’s distracting animation and they silently wondered why in the heck I wasn’t fixing this ‘bug’.

Long story short, I consulted a former coworker, @darkgoyle (who enjoys writing minified JavaScript…by hand) and in a few seconds he helped identify a better and more simple solution – and viola! [see line 20 below for details].

I give you a simple yet modern version of the javascript counter: jCount – a mashup of Mike Huggins jquery countup plugin with the javascript snippet from mredkj.com.

Okay, the reality is: this isn’t a product announcement or my own code. But, it’s a useful pattern that has been stable for my own use and I, in the interest of making someone else’s day a little easier, I just wanted to share what is now a key feature on our product’s site.

Here it is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
(function($) {

$.fn.countTo = function(options) {
// merge the default plugin settings with the custom options
options = $.extend({}, $.fn.countTo.defaults, options || {});

// how many times to update the value, and how much to increment the value on each update
var loops = Math.ceil(options.speed / options.refreshInterval),
increment = (options.to - options.from) / loops;

return $(this).each(function() {
var _this = this,
loopCount = 0,
value = options.from,
interval = setInterval(updateTimer, options.refreshInterval);

function updateTimer() {
value += increment;
loopCount++;
$(_this).html(addCommas(value.toFixed(options.decimals)))

if (typeof(options.onUpdate) == 'function') {
options.onUpdate.call(_this, value);
}

if (loopCount >= loops) {
clearInterval(interval);
value = options.to;

if (typeof(options.onComplete) == 'function') {
options.onComplete.call(_this, value);
}
}
}

function addCommas(nStr){
nStr += '';
x = nStr.split('.');
x1 = x[0];
x2 = x.length > 1 ? '.' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + ',' + '$2');
}
return x1 + x2;
}

});
};

$.fn.countTo.defaults = {
from: 0, // the number the element should start at
to: 100, // the number the element should end at
speed: 1000, // how long it should take to count between the target numbers
refreshInterval: 100, // how often the element should be updated
decimals: 0, // the number of decimal places to show
onUpdate: null, // callback method for every time the element is updated,
onComplete: null // callback method for when the element finishes updating
};
})(jQuery);

1 Comment on "Introducing jCount a JQuery countup plugin with output number formatting"

  1. Good man! You just saved me heaps of time figuring this out for myself. Cheers very much works exactly the way I wanted!

Comments are closed.

%d bloggers like this: