In this post we will try to show you how to make a countdown timer using Titanium Appcelerator for Iphone or Android applications.
First we will create an OOP countDown object that can be used independently in the background of the application and then we will connect it with some interface elements.
The countDown object
To have functional a countdown timer we’ll need to declare some properties and some methods.
As properties we will set:
time:{ m : minutes, s : seconds }, total_seconds : m*60+s |
I think this is pretty clear, time is an object with minutes and seconds and total_seconds contains the number of seconds until we reach 00:00.
We will need to set methods that will allow us to:
- set a time to count from
- stop the timer
- start it.
We also ned to set some callback functions that will be executed on each tick of the timer – fn_tick – and one that will execute when the timer reaches 00:00 named fn_end.
We won’t make a callback for start because we know when this occurs we can trigger it by ourselves.
The countDown timer will look like this:
var my_timer = new countDown( minutes, seconds, fn_tick, fn_complete); |
on this we will be able to apply
my_timer.set( minutes, seconds ); my_timer.start(); my_tmer.stop(); |
Below is the code that defines the countDown (pretty simple).
var countDown = function( m , s, fn_tick, fn_end ) { return { total_sec:m*60+s, timer:this.timer, set: function(m,s) { this.total_sec = parseInt(m)*60+parseInt(s); this.time = {m:m,s:s}; return this; }, start: function() { var self = this; this.timer = setInterval( function() { if (self.total_sec) { self.total_sec--; self.time = { m : parseInt(self.total_sec/60), s: (self.total_sec%60) }; fn_tick(); } else { self.stop(); fn_end(); } }, 1000 ); return this; }, stop: function() { clearInterval(this.timer) this.time = {m:0,s:0}; this.total_sec = 0; return this; } } } |
And now to use it in our code we will do something like this:
var my_timer = new countDown(1 , 5 , function() { //something here... }, function() { // something here... } ); my_timer.start(); |
Ok, the above example is useless, we will need to display the current time on each tick of the countdown times (so on each second) and at the end we’ll have to alert the user when we reached 00:00.
We will also need some interface elements to access the countdown methods and to display the current time.
For this we will create a label named display_lbl, that will show the time and also 3 buttons : set_btn , start_btn and stop_btn.
Creating the code is pretty simple so I won’t put the code here but you will be able to take a look at it downloading the countdown project.
What is most important is to connect the interface with the countdown timer.
So we create the timer and set the fn_tick and fn_end functions
var my_timer = new countDown(5,30, function() { display_lbl.text = my_timer.time.m+" : "+my_timer.time.s; }, function() { alert("The time is up!"); } ); |
And this is how we connect the buttons with my_timer
set_btn.addEventListener('click',function(){ display_lbl.text = "5 : 30"; my_timer.set(5,30); }); stop_btn.addEventListener('click',function(){ my_timer.stop(); }); start_btn.addEventListener('click',function(){ my_timer.start(); }); |
As you see we also set the label’s text to the initial value when we set the timer because otherwise we’ll loose the first second. We do this here to keep the timer object clean of any external interaction so we can use it even without an interface.
This is how the final project looks like

Please keep in mind that this is just a simple example and we don’t have a control mechanism to detect when the user stopped the timer or it reached by itself 00:00 – but you can add it as an exercise
You can download the Resources folder of the project from here.
Everything is MIT licensed and you can use it in any application you want to, but spreading the word would be nice.
Check the Spanish version of this post:
Crear un temporizador regresivo con Titanium Appcelerator


32 Responses
I got quite a few compiling bugs in this original code. I was able to modify it a bit to overcome them.
I also discovered that pressing the Start button multiple times makes the countdown fly, many alerts to pop-up, and the iPhone simulator to crash.
I added some code to detect if the countdown was already started and to alert the user to stop pressing start. You could also disabled the Start button.
I’d be happy to make this code available for inclusion if anyone knows who to contact.
You can send it to me, and I’ll put it here, and credit you of course
Thanks for the code:
I put the code into an Android app, and find the counter stops when I switch tasks and sometimes even when the phone goes to standby. Any ideas?
At Justin Noel:
It helps to have a variable “counting” to determine if the counter already runs and eliminate redundant button clicks.
Sorry, no idea. I tested this only on iOs.
What if you want to make a counter run like hh:mm:ss?
You will just have to change the countdown function to accept hours too.
All you have to do is to accept another argument ‘h’ and modify the function to calculate and display the new format.
Hi,
is it possible to create a pause-function to the timer and maybe call minutes and seconds from an external xml-file?
What I want is to create a timer in a podcast tableview using rss to show the remaining m’s and s’s..
hope you can help me
I’m sure it’s possible.
You would have to parse the time field in the xml and find the difference between that time and the present (when the user plays with the app). After this you only have to stop the timer, set its new value and start it again (assuming you have one counter only on the page).
In case you need a pause method it would be similar with the stop one except the lines that reset the time and seconds to 0 (comment this 2 lines ). Let me know if I understood me or you need more info.
Thx for your quick response – I think you understood it perfectly..
How do you parse a time field in an xml – I’ve tried, but there doesn’t seem to be any variable to do that – do you have a trick?
Maybe a few lines of code, as I’m new to programming
The pause method is not a must, but it would be nice to have..
You need to get the xml and it’s fields. Depending on how the time string is formatted you can try a regex or something ready made. How’s the field formatted?
The pause method you can add it yourself, as I just suggested
Forgort to mention, that my xml-file only consists of an rss-code – sorry.. I’ve never used xml before and still I’m learning basic JavaScript – so I’m pretty much a noob trying to get it
using an edited version of this code – http://pastie.org/838012 – in Titanium and a simple rss-feed like this – http://rss.cnn.com/services/podcasting/newscast/rss.xml
I was trying to load it into:
var my_timer = new countDown( THIS AREA
function() {
display_lbl.text = my_timer.time.m+” : “+my_timer.time.s;
},
function() {
alert(“The time is up!”);
}
);
But that didn’t work – should I implement the countDown-code in the pastie-example linked above?
As you can hear (and see) I’m pretty new to it all, but this is actually the first time I’m getting some good advice and help getting on.. The last few months have been struggling hard to work around my problems not getting answers in Q&A on appcelerators website..
So I’m very grateful that you are willing to help me.. Thank you!
My last comment was made in a rush as my laptop battery level was at 2 % – with this saying that I should have been more detailed in my description of what i didn’t understand
I’ve never worked with xml before, so I’m pretty much unaware of how those fields work – what I tried out was to add fields in my rss like this:
something
1,2,
etc…
then load the description into my_timer instead of 1,2,
var my_timer = new countDown( MY CONTENT HERE (rss-description)
function() {
but that didn’t work.. Maybe I should mention that I’m using this code to load my rss-feed/xml-file – http://pastie.org/838012
Implementing the timer into the “pastie”-code didn’t seem to work either – I’m pretty sure that this is just a simple problem, but as you can hear, I’m pretty new to this JavaScript-programming – so I’m so happy that you’re willing to help and give me some advice..
The last couple of months I’ve had to solve problems by myself – I’ve never got a solution to my problem in Q&A on the appcelerator-forum :/
That can be quite hard being a noob!
I’m so grateful for your help – thank you.. Please say if I should make myself more clear or paste some of my own code.. This is just such a simple feature, but very necessary when making a music-app
I think the field you need is the length, right?
In this case you just have to get it as you get the url of the audio
mp3_length = itemList.item(c).getElementsByTagName("enclosure").item(0)
.getAttribute("length");
I think this is in ms so from here you need to convert the ms into minutes and seconds to adapt it to the timer script
ms_time_m = parseInt((mp3_length/1000)/60);ms_time_s = (mp3_length/1000)%60;
and
counter = new countDown(ms_time_m,ms_time_s, fn_tick, fn_complete);Download the code to see how fn_tick anf fn_complete are used.
Thx again – now I have the timer recognizing my mp3_length variable, but it still doesn’t count down nor does it convert ms to m and s. It shows in display_lbl – but that’s it.
I’ve put the “ms_time_m = parseInt((mp3_length/1000)/60);
ms_time_s = (mp3_length/1000)%60;” in the countDown-part, but maybe it is in the wrong place?
It also shows a bug with the “var my_timer = new countDown(ms_time_m,ms_time_s, fn_tick, fn_complete);”
How does the constant variables like “new countDown(1,30,” and “my_timer.set(5,30);” change? I’ve tried placing “e.rowData.mp3Length” instead, but that doesn’t have any effect at all – it shows a bug!
Post some code on pastie to see what’s there, I cannot tell without it.
Okay, so here is my code http://pastie.org/1588443
This:
stream.addEventListener(‘progress’, function(e){
Titanium.API.info(‘Time Played: ‘ + Math.round(e.progress) + ‘ seconds’);
});
shows the duration as the podcast plays, but only in seconds – maybe I could use this if there’s a way to convert it, as it doesn’t necessarily have to be a countdown – it might as well be an indication of how long the song have been playing!
yes, you could use this, which I think is better than to use a separate timer.
Maybe like this:
stream.addEventListener('progress', function(e){Titanium.API.info('Time Played: ' + Math.round(e.progress) + ' seconds');
display_label.text = parseInt(e.progress/60)+':'+e.progress%60;
});
this will show you something like : 12:34. If the file is bigger than 60 min you will need to adjust your algorithm.
Thx, that did the trick
sort of..
I edited it a bit:
stream.addEventListener(‘progress’, function(e){
Titanium.API.info(‘Time Played: ‘ + Math.round(e.progress) + ‘ seconds’);
item_counter_label.text = parseInt(e.progress/60)+’:'+Math.round(e.progress)%60;
});
Now the problem to fix, is that it shows like this 0:1, 0:2, 0:3 –> 1:0, 1:1, 1:2 etc.. When it would be best to have it like this 0:01, 0:02, 0:03 –> 1:00, 1:01, 1:02 etc..
Is there a workaround for this or should I just be happy that it works?
Hi again..
It turns out it only did the trick less than sort of..
Now, if I choose a podcast it plays and the counter ticks, but if I choose another podcast, the counter doesn’t respond – not even in API.info… If I go back to the first podcast it doesn’t respond either.. Seems the evenListener can only recognize the duration when clicking the first time!
Is there an explanation to this or am I just not seeing the obvious?
/Anders
Ok, make a zip with your Resources folder and put it somewhere I can take it. I will try to take a look at it.
Hi Dan,
I’ve sent you a link to my Resources folder with an e-mail..
Hope you’ll get a chance to look at it..
Hi, your email refuses to receive emails from me.
Please provide me an url to get he feed with the songs form because else I cannot test.
I’ve just sent you an email with the xml-feed..
It seems that the audio player looses the progress event when you change the track. There is another bug related to the change event ( even for me it seems to work ) but might be related. I’ll try to create a test case and submit a bug to the Appcelerator. I think you might have to recreate a stream each time you want to change the track until they fix the bug or reply me.
Okay, either way, thank you so much for your help!
What I really want to do is to create a player playing a playlist – there’s still no way to use the native music player with url-files, is there?
Not sure,
I submitted the bug, I’ll keep you posted here when I’ll have news.
Thank you very much for your time
It’s dodgy on Android. I have to ignore this tutorial. Others are great though.
The guys from Appcelerator updated with my source an already existent bug.
So you might want to watch this ticket to know when it’s done.
https://appcelerator.lighthouseapp.com/projects/32238-titanium-mobile/tickets/2901
Don’t ignore it! Make it work and share with the community
Cool, I definitely won’t
But meanwhile I’ll try a different solution – thank you again for your help Dan..
Just to be clear – I’ll definitely won’t ignore it, but I’ll definitely share it