Building an extensible jQuery countdown plugin from scratch

UPDATE!
I’ve made an official release of this plugin, click here and check it out

It has been some time since I’ve last posted, I’ve been far too busy with a project I’ve been working on the past several months, but it’s almost ready and I hope I’ll get back to my weekly posting.

While working at this project, at some point I needed a countdown script to announce certain features being released on specific dates, maybe I’ve been a bit lazy and tried finding an already built countdown plugin to work with, but not much luck finding exactly what I was looking for so I’ve built my own.

Inspired from the countdown plugin video from The New Boston, I’ve decided to make this tutorial so everyone can be able to create their very own extensible jQuery countdown plugin.

If you don’t want to read the tutorial and just download the ready-to-use jQuery countdown script, then click here and read the instructions.txt file.

The point to build our own countdown script is to be able to have full control over it, to make it extensible and to be able to reuse it throughout our projects very easily.

Setting up our workspace

For this, we will obviously need the jQuery library which you can download from their website right here, but if you already have it, do make sure it’s the last stable version.

I’m assuming you already know how to create files and folders :) so create a folder for the CSS and one for the JavaScript files, because we want to be clean and work with unobtrusive code.

You can also download my clean workspace for this tutorial clicking here.

It’s entirely your decision where the countdown is positioned and how it is styled, but to keep this tutorial simple, we’ll use a basic look & feel and afterwards you can implement it as you wish.

Let’s create the HTML structure for the countdown:

index.html

The external stylesheet which goes in the CSS folder, containing some basic styles:

countdown.css

And in the JS folder goes the jQuery library.

Right now all we have is a static looking countdown, so let’s add the logic and build the plugin.
In the JS folder, create a file countdown.js, open it with your favorite code editor and let’s get to work.

We will build all of our code inside a plugin function that jQuery recognizes:

countdown.js

A jQuery plugin function requires a name and in our example we gave it countdown
Also, you’ll notice that the main function has a dollar sign parameter and the jQuery keyword at the end between paranthesis, if we wouldn’t have done that, we no longer could’ve used the short jQuery dollar sign namespace (i.e. $(“h1″) ) and had to use jQuery’s regular namespace (i.e. jQuery(“h1″) ).

It’s always good practice to test your functions before you start coding, a quick way to do it is to add a simple alert function and then just call it from an HTML page:

countdown.js

Now let’s test the plugin by calling it from our index.html

index.html

If you didn’t mistype anything, you should get an alert with the message “Hello!” when you open or refresh the page.

When you get different results than those mentioned in this article, try downloading the examples.

The beauty of a plugin is the control we can add to it by extending it with parameters where we can specify certain settings and a callback function that launches a code we want after it has successfully finished processing.
We’ll add two parameters to our plugin function, settings and callback.

countdown.js

Now that we have specified that our plugin requires two parameters, options and callback, let’s start adding our custom settings.
In our case, we’ll need to be able to add a date which we can make the plugin read and process.
We’ll specify our settings via an array, but we’ll start with just one setting for now:

countdown.js

By default, we’ve set it to null so it would be empty if no date will be specified when calling the plugin.
Also, you’ll notice at the begining a new variable called thisEl (which can be called whatever you want), we added the $(this) selector onto this variable so we can easily reference our countdown’s html code later on. If you do not know what this means in JavaScript, do look it up as it’s one of the key elements of JavaScript.

To make the plugin’s options parameter recognize our settings array and reference all of our settings from it, we’ll use jQuery’s $.extend function

countdown.js

We’ve told it that if the options parameter exists, then append the settings array to it.

So now we’re able to call the plugin and specify a date.

index.html

We’ve applied the plugin onto an HTML’s countdown ID that holds the HTML elements for the countdown, this way the plugin will be much faster and won’t have to tranverse through the entire DOM to find the elements that it needs to interact with.
Now that we’re done with the basics, let’s get to the real processing.

But first! Let’s see how we can read the date value we specify when calling the plugin.
We’re going to create a new function inside our plugin called countdown_proc and we’re going to alert the date.

countdown.js

Since we assigned the settings array to be the place where we specify all of our properties, to fetch the date we use settings[‘date’]. And if you add more properties, just use settings[‘PROPERTY_NAME’].
Now when you open or refresh the page, it will alert the date value you specify in your html page when calling the plugin.

Remove the alert and let’s make this plugin actually do something 😉
We’ll need two variables that will hold the current and end date. We’ll get the current date using the jQuery’s $.now() function that fetches the current date. The end date will be specified when calling the plugin so we’ll fetch it from there.

countdown.js

To avoid confusion, let’s talk about date for a bit. We created the variable eventDate and we need to asign the date we specify when calling the plugin, like mentioned in the previous example (i.e. date: “4 december 2011 11:20:00″ ).
But what we really need is a timestamp date (number of seconds). So when we fetch the date value, we’ll also convert it into a timestamp date by using the Date.parse function, this will however give us the timestamp in milliseconds so we just divide it by 1000. Thus Date.parse(settings[‘date’]) / 1000 results the timestamp in seconds.
As for the currentDate, jQuery has a function named $.now() that fetches the current date in milliseconds, again, we divide it by 1000 to work with seconds.

We have both variables for Current Date and for End Date, we’ll need to calculate the difference so we can populate the countdown with the difference between them, the remaining time that is.
We’ll create a variable seconds where we’ll do a simple math substraction to find out the number of seconds between the current and end date.

countdown.js

Now that we know the remaining time in seconds, let’s calculate the number of days, hours, minutes and seconds and add them to variables which we can later use.

countdown.js

Let’s explain days and you’ll figure out the rest of the math. To calculate the number of days, we used a simple math calculation where we divided the total number of seconds by a day (in seconds). A day has 86400 seconds, but just so we don’t have to remember how many seconds a period of time has, we just used (hours * minutes * seconds), equaling the number of seconds in a day. Thus, number of seconds divided by (60 * 60 * 24) => seconds / seconds in a day. Wow, I think I’m being way too explanatory here.
The Math.floor function that surrounds our math calculation does nothing more but to remove the remainder from our result and consider only the floor value of it, just so we won’t get results such as 3.3164400 days.

You’ll notice the seconds variable right afterwards, doing a math calculation with -=. What that does is remove the number of seconds used in the days variable so we can have an updated seconds variable without the number of days in order to continue calculating the hours, minutes and seconds.

And the process repeats for hours, minutes.

Finally the fun part, let’s populate our countdown’s html span values:

countdown.js

If everything went well, each time you refresh the page and you should see the countdown updated with the remaining time.
We’ve used the thisEl variable to start working directly with the code of our countdown html portion, using .find to find the elements we want to update.

We do need to make the countdown update itself each second though, so we’ll just loop the process every second with the help of JavaScript’s setInterval function, we’ll add it after the countdown_proc function:

countdown.js

Now you should see the countdown updating itself each second.

setInterval requires the code you want to run and at what interval you want it to run (in milliseconds).
We’ve run it by also adding it to an interval variable so we can have control over it and in our case, stop it whenever the countdown finishes.

Even though the countdown’s working now, we still have a few more things to fix, or at least to consider.

If you’ll call the plugin with an event date that happens in a minute or so, you’ll notice that once it reaches time 0, it will not stop and start showing negative values. Let’s fix that.

Right after the eventDate and currentDate variables, let’s add the following condition

countdown.js

What the condition basically does, is check whether the eventDate variable (that holds the timestamp date value of our event) is equal or less than the currentDate variable, if so, run the callback (the one we’ll specify when we’ll call the script in out html page) and also to clear the interval, at that point we no longer need the interval to keep looping our countdown script since the countdown ended.

Hoping that all of that was clear, let’s test it one more time and also make it alert a message when the countdown ends.

index.html

countdown.js

As callback, we added an alert with the message “Countdown finished” that will show up when the countdown ends.
Now you have a functional countdown which you can use to announce features on a website, or perhaps the launch of an website itself.

We can however enhance this countdown even further.

Constant double digits setting

Depending on how you style the countdown, it can become inconsistent if the time displays both in single and double digits (i.e. 5:0:54 / 17:15:54), or maybe you want it to aways display with double digits for visual reasons only.
To achieve that, we’ll extend this plugin by adding one more setting, that is to turn on and off the display of double digits.
We’ll start by adding format as our new setting name with the value of null, in our settings array:

countdown.js

We’ve set the value to null because we want it to hold no value as long as we do not set it when we call the plugin.
In our countdown.js script file, right after the last seconds variable we will add the following condition:

countdown.js

The reason why we want to have this condition set after the days, hours, minutes, seconds variables is because we want those variables to already exist and hold the real countdown values so we can now check whether their values are formed by two digits or not, and if not, we’ll add the missing 0.
So what we’ve done is to check if the format settings is set to ON and if so, check whether the values are formed by two digits and if not, add the missing zero.
The condition is quite simple and it’s exacty as an if-and-else statement.

Basically:

Is the same as:

So if the days variable has two digits or more, leave it as it is, otherwise it must be made of just 1 character so append a 0 to it.

As a result we should have:

countdown.js

and to force it to display two digits, we’ll call the plugin by specifying our format setting to ON.

index.html

Now the plugin has two settings to play with.
But it’s not yet an entirely fail-safe plugin, I say we should add a warning in case the date that’s added when calling the plugin is incorrect.
To do so all we have to do is wrap our *.text() methods in a condition where we check whether our eventDate variable is a number, if it’s not, that means the specified date is invalid and has been no longer successfully converted into a numerical timestamp.

countdown.js

We used the isNaN function (which means is Not a Number) and prepended an exclamation mark to it to reverse the condition, so now it’s checking whether it is a number (!isNaN = if it’s not Not a Number).
And if it’s not, we just apply an alert with a warning and clear the interval to stop the timer.

What about the S endings of day(s) minute(s) when it actually display 1 as value?
We should make it display day when it shows 1 day and days when there are more days left.

Conditioning the Ss

To start, we’ll need to add a different class for each time reference (timeRef for days will become timeRefDays, for hours it will be timeRefHours and so on).

index.html

countdown.css

We already have access to our variables that display the coundown time, all we have to check is whether it’s 1 or not. If any time duration is 1, remove the s, otherwise show it.
Right before our format setting code, let’s add conditions for each time reference:

countdown.js

And there we have it! Man, me and my long articles :/
I hope that all the details at each step somehow helped you and didn’t actually clutter your mind more hehe

Here’s the final code:

index.html

countdown.css

countdown.js

Once you’ve read the entire tutorial, all the code should no longer look difficult at all, in fact, keep spending some time playing with it, get comfortable with it, add more control as needed.

In fact, I’ll reward the first person who makes the countdown change its color once it’s about to end, and the time that it should start changing its color should be specified as a setting.

Reward: A free link in the footer of this blog for 3 whole months* :)

* Yes, that little pesky star, I’ll have to specify that I won’t be accepting any website that contains rude, obscene or racist content.

The code is free to use for both personal and commercial purposes, however, do try to subscribe, tweet, like and so on… share the love!

Good luck!

UPDATE!
I’ve made an official release of this plugin, click here and check it out

Catalin

My name is Cătălin Berța and I'm a front-end web developer. I was born in Focsani, Romania and currently living in Bucharest. Started playing with some good old html tables ever since 2004 as a hobby, turned out to be a full-time career! :) I've had the chances to experience and witness web development's rapid growth over the years where I've mainly focused on front-end web technologies.

30 thoughts on “Building an extensible jQuery countdown plugin from scratch

  1. Awesome Tutorial Catalin-I have never used jquery but to link to it as part of a script.

    I am going to try and ‘setting’ to change color as you challenged.

  2. Pingback: HowTo: Build an extensible jQuery countdown plugin from scratch … | EtondeGroup Blog of Web Applications
  3. I’ve never used this jQuery. This time ‘m going to try out, well thanks for the tutorial, its been a great help.

  4. Thanks for the well indeed tutorial in creating the HTML structure for the countdown, But I can’t say that I’m good enough to catch up immediately the ideas that you share here, Because I’m not really familiar about it. However, Thanks a lot.

  5. Where is this countdown plg going to? :)) Ok, I must have the countdown with negative values after 0 time. I delete the code from “if(eventDate <= currentDate) {". And what I can find here? First – the first negative sign. It's right, couse we are on the second side of the 0. Second – is the time upgoing? NO, the time is downgoing to … the midnight of today!!! (start date 01 march 2012 00:00:00) Can you fixt it?
    Second matter – how much of instances of this script can be displayed at one page? I need from 10 to 50, with different times. brgs, thank you for your lesson of Query, very fine for beginners. Thank You.

  6. can you change the incoming date format into (yyyy-mm-dd hours:minutes:seconds) or (yyy,mm,dd,hours,minutes,seconds)? It will be better to load it from dbase ..

  7. I’m having a hard time understanding the end result you’re expecting for this countdown to do.

    Can you please describe in details exactly what you’re trying to achieve? I’ll see if I’ll find the time to do it for you :-)

  8. Pingback: My Stream | Adding a jQuery Countdown to Our “Coming Soon” Page | My Stream
  9. Is reward gone..? 😀

    Thanks for this one, mate, it’s great in so many aspects ! Keep on posting, that will be greatest reward. :)

    Cheers

  10. And, I forgot a small ”update” – in my native language, every number that ends with 1 is singular word (20 days, but 21 day), so in this case “Ss” must detect last number. I achieve that with assigning new var to check substr(id.length – 1) (where id is days/hours/minutes/secs), and then put that new var in if statement –

    if (newVar == 1) { selector.find(‘timeRefDays’…)

    Just for the record, if anyone else needs this. :)

  11. @Unity3D
    Reward is still available :)
    Awesome work! I didn’t know about your special case of numbers ending in 1 being as singular words.
    Thanks for contributing with the solution!

  12. First of all, this was an awesome tutorial. I love that you went into this much detail because it allowed me to actually understand a few new aspects of jQuery. I much prefer an approach like this than simply a block of code to be copied in order to perform some function.

    That said, after building this plugin and adapting it to count down from an arbitrary amount of time (10 mins), I had to abandon it and extract the functionality to a regular set of functions for one simple reason: Even though I was able to get the countdown to work, I could not figure out how to stop the countdown through a click event on a button, which was an essential part of what I was trying to accomplish.

    If you could add some instruction and explanation on how to stop/clear the countdown by clicking on some element (button, div, etc.) – and how to more generally call functions inside of a plugin directly – then I think that would make the plugin complete and even more extensible.

  13. @Ryan
    Thanks for the awesome feedback!
    That sure sounds like an essential feature this plugin should have, I’ll do it somewhere today, update the plugin and get back to you via mail :)

    P.S. I’m already recoding this plugin entirely and planning to release soon a better built and customizable plugin with essential features, such as real-time (timezone based) countdown, custom duration length and more.

    I’ll also consider all the feature requests from these comments.

    Cheers

  14. @Ryan
    In the end, I had to tweak the plugin and make a custom version and I mailed it to you, I’m not publishing these changes as they’re going to be featured in the new version I’m planning to release soon.
    Let us know how things work out for you :)
    Cheers

  15. Hi Catalin,

    I just now had a chance to take a look at the plugin. Thanks again for that. Everything looks good. My only question is: Do the pause, stop and start functions need to be declared inside of the countdown_proc() function or could they be declared outside of it?

    Actually, one more question: Do you need both of these?

    //run the function
    countdown_proc();

    //loop the function
    interval = setInterval(countdown_proc, 1000);

    Wouldn’t the loop start the function anyway?

    Thanks,
    Ryan

  16. @Ryan
    You can move them outside of the function, yes. Mind me asking why you’d want to do that?

    And yes, you need both calls to that function. If you’d leave only the setInterval, the countdown would have one second delay before it would start and I doubt you want that. The fact that we call it before regularly:

    //run the function
    countdown_proc();

    starts instantly and then the setInterval continues by looping it ‘after’ each second:

    //loop the function
    interval = setInterval(countdown_proc, 1000);

  17. Hi Catalin,

    It’s not so much that I would necessarily make that changed for this particular plugin. I’m just trying to get a better understanding of how to write and work with jQuery plugins. I think it would be a great idea for a tutorial to cover that topic in the same detail as you’ve covered this tutorial for creating a specific countdown plugin. So far I’ve found it somewhat difficult to find resources that explain all the plugin concepts clearly.

    As for starting the procedure and then starting the loop and the fact that just starting the loop would cause a one second delay … in this particular instance that does actually accomplish what I was looking for. On the project I’m on, there’s a 10 minute counter that start when you press a button and that button also happens to start a process with an AJAX call that will stop at the end of 10 minutes. But starting with the loop instead of starting the process directly, I actually see the one second display of 10:00 rather than visually starting with 9:59. I actually want to see that 10:00 for a second and it gives the process a second to start through the AJAX call.

    Ryan

  18. I’m glad you managed to tweak it so it would fit your needs, then.
    A tutorial about extending a plugin with methods sounds good, but it will have to be after I finish the countdown, as I’m working on an official release.

    Cheers

  19. Hi Catalin, the countdown doesn’t seem to work in IE9 Here is the example loaded: http://rewards.shophqf.com/js/020-final/index.html

    In exchange for your help (or if anyone else would like). I have modified this script to allow for multiple countdowns on one page and the ability to also start the timer with a timestamp from the web server. I would be happy to share it with anyone that is interested.

  20. I found the problem! This is really weird, but for some reason, IE9 does not like the tag. If you replace all the with it counts down fine in IE9 too!

  21. Hey how can i change the language, when i change this its coming in Eng only, can you suggest me how to change the days ,hours…etc to other languages

  22. Thank you for the useful tutorial – I’m working on making a simple countdown Android app to learn jQuery – this will definitely help!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">