Experiment – Up Counter

For a recent prototype, I was asked to create a ‘donation counter’ to depict the live updating of a total as it went up. However without any data to connect with this needed to just give the impression of the behaviour. The result was a useful bit of code and a little bit of jQuery extension. Let’s get cracking.

So with all mini challenges I start by setting out what the ‘up counter’ would need to achieve:

• Counter up in random amounts
• ‘Re-count’ at random times and not regularly
• Properly format the resulting number so it’s not just one long string

The first two points on the list can be ticked off with the use of Math.random. Firstly, we add the result of Math.random (always between 0 and 1) to the maximum amount we want the counter to go up by at any one time. I have used 500 as an example. This means when the function is called anything between 0 and 500 is added.

Secondly, we can use setTimeout to control when the function is called after it has been run. Here we use the following equation:

Math.round(1000+Math.random()*3000)

We use Math.random like before and multiply it by 3000 which is equivalent to 3 seconds. However this time we have added 1 second beforehand to prevent the potential of the function being executed again less than a second after it was called; it will now get called any time between 1 and 3 seconds. This is purely to avoid the counter looking too frantic, but you can remove this if you don’t want this addition. We then call Math.round to provide a nice round number to setTimeout.

So far, our upCounter function can be called on load, will add a random amount to our running total, and will continue to do so at random intervals:

var count = 100;

function upCounter(){
  var targetElement = $('span.counter');
// Add a random amount between 1 and 500 to the counter
    count += Math.round(Math.random()*500);
    targetElement.fadeOut(function() { 
    targetElement.text(count)
                     .fadeIn();
  });
// Set a delay for a time between 1 and 3 seconds then run the function again
  setTimeout(upCounter,Math.round(1000+Math.random()*3000));
}
upCounter();

For the final requirement, I did a bit of searching and was surprised that I couldn’t find any neat little solutions to punctuate a string appropriately. Therefore I decided to write my own with a little bit of regex magic. The following code simply grabs the number within the element provided and adds a comma every third digit from the right, as that is how numbers are formatted (at least up to the billions, and if a charity are receiving donations like that then they can afford to commission a better counter to be made!)

// Extend the jQuery library
$.fn.punctuate = function(){ 
// each function in case we ever want to use it more than once
  return this.each(function(){ 
// Take the text in the target element and add a comma every third digit from the right
    $(this).text( $(this).text().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,") ); 
  })
}

The result is the following:

$.fn.punctuate = function(){ 
  return this.each(function(){ 
    $(this).text( $(this).text().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,") ); 
  })
}

// Set the default value the counter starts at
var count = 200;

function upCounter(){
  var targetElement = $('span.counter');
  count += Math.round(Math.random()*500);
    targetElement.fadeOut(function() { 
    targetElement.text(count)
                     .fadeIn();
    targetElement.punctuate();
  });
  setTimeout(upCounter,Math.round(1000+Math.random()*3000));
}

// Call on load
upCounter();

You can obviously tweak the longest possible time before updating or the largest amount it could add at any one time to fit your needs.