Pomodoro Timer via setTimeout() I've made my attempt to code timer entirely by hand using jQuery. No external libraries to manage time at all.



$(document).ready(function() {
 var setSessionMinutes = 5,
  setBreakMinutes = 5,
  sessionMinutes = setSessionMinutes,
  breakMinutes = setBreakMinutes,
  counterSeconds = -1,
  countTimeout,
  runState = false;

 function setClockValues() {
  $('#break').html(setBreakMinutes);
  $('#session').html(setSessionMinutes);
  $('#time').html(formatTime(setSessionMinutes, 0));
  sessionMinutes = setSessionMinutes;
  breakMinutes = setBreakMinutes;
  counterSeconds = -1;
 };
 setClockValues();

 function formatTime(minutes, seconds) {
  minutes = minutes &gt;= 10 ? minutes : '0' + minutes;
  seconds = seconds &gt;= 10 ? seconds : '0' + seconds;
  return minutes + ':' + seconds;
 }

 //change values by buttons
 $('#minusbreak').click(function() {
  $('#break').html(setBreakMinutes &gt; 0 ? --setBreakMinutes : 0);
  breakMinutes = setBreakMinutes;
 });
 $('#plusbreak').click(function() {
  $('#break').html(++setBreakMinutes);
  breakMinutes = setBreakMinutes;
 });
 $('#minusSession').click(function() {
  $('#session').html(setSessionMinutes &gt; 0 ? --setSessionMinutes : 0);
  $('#time').html(formatTime(setSessionMinutes, 0));
  sessionMinutes = setSessionMinutes;
 });
 $('#plusSession').click(function() {
  $('#session').html(++setSessionMinutes);
  $('#time').html(formatTime(setSessionMinutes, 0));
  sessionMinutes = setSessionMinutes;
 });

 function countDown() {
  if (counterSeconds &lt; 0 &amp;&amp; sessionMinutes &gt;= 0) {
   --sessionMinutes;
   counterSeconds = 59;
  }
  $('#time').html(formatTime(sessionMinutes, counterSeconds));
  --counterSeconds;
  if (counterSeconds &gt;= 0 &amp;&amp; sessionMinutes &gt;= 0)
   countTimeout = setTimeout(countDown, 1000);
  else {
   $('#finish').get(0).play();
   setTimeout(countDownBreak, 1000);
  }
 }

 function countDownBreak() {
  if (counterSeconds &lt; 0 &amp;&amp; breakMinutes &gt;= 0) {
   --breakMinutes;
   counterSeconds = 59;
  }
  $('#time').html(formatTime(breakMinutes, counterSeconds));
  --counterSeconds;
  if (counterSeconds &gt;= 0 &amp;&amp; breakMinutes &gt;= 0)
   countTimeout = setTimeout(countDownBreak, 1000);
  else {
   stopCountDown();
   $('#status').html('start');
   runState = false;
   $('#finish').get(0).play();
  }
 }
 function stopCountDown() {
  clearTimeout(countTimeout);
  setClockValues();
 }

 //   start/stop timer
 $('#status').click(function() {
  switch (runState) {
   case false:
    $('#status').html('reset');
    countDown();
    runState = true;
    break;
   case true:
    $('#status').html('start');
    stopCountDown();
    runState = false;
    break;
  }
 });

});




You can also see it on CodePen.io.

I realise this code should be 3/4 or even half current length, more DRY etc., but I'd like to get some opinions about code without much optimization to know better where I currently am with my progress. After all, I could spend 12 hours to make it beautiful (which I eventually will), but that would destroy purpose of this post.

About setTimeout instead of setInterval: I did it on purpose because of this.
Feedback

I know it has been nearly 3 years since this was posted and you likely have learned more about javascript and jQuery since then. Perhaps the information below is old news but nevertheless...

I like the styles and the sound that plays when the timer is done is fun! I did notice that if I decrease the Session Length to 0 and click the start button, it shows -01:59 and then appears to jump up to 05:58. Perhaps it would be wise to not allow the user to click the start button if the value for session length is 0. 

Recommendations

I only see a couple things I would change:


It is recommended that DOM elements be stored in a variable - e.g.  

var breakElement = $('#break');


And then later on use breakElement instead of $('#break') - e.g.

breakElement.html(setBreakMinutes);

The switch statement at the end seems a bit heavy - why not just use an if/else:


switch (runState) {
        case false:
            $('#status').html('reset');
            countDown();
            runState = true;
            break;
        case true:
            $('#status').html('start');
            stopCountDown();
            runState = false;
            break;
    }



While it is only few lines shorter, there is no need to remember the break statements: 

if (runState) {
    $('#status').html('start');
    stopCountDown();
    runState = false;
}
else {
    $('#status').html('reset');
    countDown();
    runState = true;
}