Stopwatch app using Dojo Here is the link to fiddle. This is my first app using Dojo. Any comments/feedback is highly appreciated.

dojoConfig = {parseOnLoad: true};

resetStopwatch();

require(["dijit/form/ToggleButton", "dijit/form/Button", "dojo/dom", "dojo/dom-attr", "dojo/domReady!"], function(ToggleButton, Button, dom, domAttr){

    var timeUpdate;

    var toggleButton = new ToggleButton({
        showLabel: true,
        checked: false,
        label: "Start",
        onChange: function() {
            if (this.get('label') == "Start") {
                this.set('label', 'Stop');

                var milliseconds = seconds = minutes = hours = 0;

                timeUpdate = updateTime(domAttr, 0, 0, 0, 0);
            } 
            else if (this.get('label') == "Resume") {
                this.set('label', 'Stop');
                // fetch current time in the stopwatch
                prev_milliseconds = parseInt(domAttr.get("milliseconds", "innerHTML"));
                prev_seconds      = parseInt(domAttr.get("seconds", "innerHTML"));
                prev_minutes      = parseInt(domAttr.get("minutes", "innerHTML"));
                prev_hours        = parseInt(domAttr.get("hours", "innerHTML"));
                timeUpdate = updateTime(domAttr, prev_hours, prev_minutes, prev_seconds, prev_milliseconds);

            }
            else if (this.get('label') == "Stop"){
                this.set('label', 'Resume');
                clearInterval(timeUpdate);
            }
        }
    }, "start_stop_resume");

    var resetButton = new Button({
        label: "Reset",
        onClick: function(){
            toggleButton.set('label', "Start");
            clearInterval(timeUpdate);
            resetStopwatch();        
            resumeFlag = false;
        }
    }, "reset");
});

function updateTime(domAttr, prev_hours, prev_minutes, prev_seconds, prev_milliseconds){
    var startTime = new Date();
    timeUpdate = setInterval(function(){
        var timeElapsed = new Date().getTime() - startTime.getTime();

        // calculate hours                
        hours = parseInt(timeElapsed/1000/60/60) + prev_hours;
        hours = prependZero(hours);
        domAttr.set("hours", "innerHTML", hours + " : ");

        // calculate minutes
        minutes = parseInt(timeElapsed/1000/60) + prev_minutes;
        if(minutes &gt; 60)
            minutes = minutes % 60;
        minutes = prependZero(minutes);
        domAttr.set("minutes", "innerHTML", minutes + " : ");

        // calculate seconds
        seconds = parseInt(timeElapsed/1000) + prev_seconds;
        if(seconds &gt; 60)
            seconds = seconds % 60;
        seconds = prependZero(seconds);
        domAttr.set("seconds", "innerHTML", seconds + " :: ");

        // calculate milliseconds 
        milliseconds = timeElapsed + prev_milliseconds;
        milliseconds = prependZero(milliseconds);
        if(milliseconds &gt; 1000)
            milliseconds = milliseconds % 1000;
        if(milliseconds &lt; 10)
            milliseconds = "00" + milliseconds.toString();
        else if(milliseconds &lt; 100)
            milliseconds = "0" + milliseconds.toString();                
        domAttr.set("milliseconds", "innerHTML", milliseconds);

    },25);  // update time in stopwatch after every 25ms

    return timeUpdate;

}

function resetStopwatch(){
    require(["dojo/dom-attr"], function(domAttr){
        domAttr.set("hours",        "innerHTML", "00 : ");
        domAttr.set("minutes",      "innerHTML", "00 : ");
        domAttr.set("seconds",      "innerHTML", "00 :: ");
        domAttr.set("milliseconds", "innerHTML", "000");
    });
}

function prependZero(time){
    if(time &lt; 10){
        time = "0" + time.toString();
        return time;
    }
    else
        return time;
}
I tinkered a bit with the fiddle, I have the following observations:


If you were to place the colons in the HTML, then you would no longer need to concatenate the colons into the time fields:


&lt;div id="stopwatch"&gt; 
  &lt;span id="hours"&gt;&lt;/span&gt;:
  &lt;span id="minutes"&gt;&lt;/span&gt;:
  &lt;span id="seconds"&gt;&lt;/span&gt;::
  &lt;span id="milliseconds"&gt;&lt;/span&gt;
&lt;/div&gt;


You could generalize prependZero so that it works for both seconds and milliseconds by passing the requested length:


  function prependZero( time, length ){
      time = time + "";
      while( time.length &lt; length ){
      time = '0' + time;
    }
    return time;
  }



or a more Golfic version which calculates the amount of zeroes that will be required:

function prependZero2( time, length ){
    time = time + "";
    return new Array( Math.max( length - time.length + 1 , 0 ) ).join("0") + time;
}

if(minutes &gt; 60) minutes = minutes % 60; is the same as minutes = minutes % 60; is the same as minutes %= 60;.
Your code would be much cleaner if you split out time calculations from prettyfying the numbers.

You could have a function that is dedicated to time calculations:

function updateTime(domAttr, prev_hours, prev_minutes, prev_seconds, prev_milliseconds){
  var startTime = new Date();
  timeUpdate = setInterval(function(){
    var timeElapsed = new Date().getTime() - startTime.getTime();

    // calculate hours                
    hours = parseInt(timeElapsed/1000/60/60) + prev_hours;

    // calculate minutes
    minutes = parseInt(timeElapsed/1000/60) + prev_minutes;
    minutes %= 60;

    // calculate seconds
    seconds = parseInt(timeElapsed/1000) + prev_seconds;
    seconds %= 60;

    // calculate milliseconds 
    milliseconds = timeElapsed + prev_milliseconds;
    milliseconds %= 1000;

    setStopwatch( hours , minutes , seconds , milliseconds );

  },25);  // update time in stopwatch after every 25ms

  return timeUpdate;
}


and a function that just updates the DOM:

function setStopwatch( hours , minutes , seconds , milliseconds ){
    require(["dojo/dom-attr"], function(domAttr){
        domAttr.set("hours"       , "innerHTML", prependZero( hours, 2 ) );
        domAttr.set("minutes"     , "innerHTML", prependZero( minutes, 2 ) );
        domAttr.set("seconds"     , "innerHTML", prependZero( seconds, 2 ) );
        domAttr.set("milliseconds", "innerHTML", prependZero( milliseconds, 3 ) );
    });
}


resetStopwatch then becomes as simple as 

function resetStopwatch(){
    setStopwatch( 0, 0, 0, 0 );
}

A very minor nitpicking, but the require array is hard to read, you should figure out how Dojo proposes you should indent that array.
Another nitpicking is that you trust the DOM as your data model (you retrieve the values from the labels when you hit Resume), that is a bad practice in general, but acceptable for a timer project.


You can check the end result here.