Reputation: 15501
Here is my code so far:
dojoConfig = {parseOnLoad: true};
resetStopwatch();
require(["dojo/query", "dijit/form/ToggleButton", "dijit/form/Button", "dojo/dom", "dojo/dom-attr", "dojo/domReady!"], function(query, ToggleButton, Button, dom, domAttr){
//query("#resume").style("display", "none");
var timeUpdate, flag;
flag = false;
new ToggleButton({
showLabel: true,
checked: false,
onChange: function(val) {
if (val) {
this.set('label', 'Stop');
var milliseconds = seconds = minutes = hours = 0;
if(flag){
// fetch current time in the stopwatch
milliseconds = parseInt(domAttr.get("milliseconds", "innerHTML"));
seconds = parseInt(domAttr.get("seconds", "innerHTML"));
minutes = parseInt(domAttr.get("minutes", "innerHTML"));
hours = parseInt(domAttr.get("hours", "innerHTML"));
}
var startTime = new Date();
timeUpdate = setInterval(function(){
var timeElapsed = new Date().getTime() - startTime.getTime();
// calculate hours
hours = parseInt(timeElapsed/1000/60/60);
hours = prependZero(hours);
domAttr.set("hours", "innerHTML", hours + " h ");
// calculate minutes
minutes = parseInt(timeElapsed/1000/60);
if(minutes > 60)
minutes = minutes % 60;
minutes = prependZero(minutes);
domAttr.set("minutes", "innerHTML", minutes + " m ");
// calculate seconds
seconds = parseInt(timeElapsed/1000);
if(seconds > 60)
seconds = seconds % 60;
seconds = prependZero(seconds);
domAttr.set("seconds", "innerHTML", seconds + " s ");
// calculate milliseconds
milliseconds = timeElapsed;
milliseconds = prependZero(milliseconds);
if(milliseconds > 1000)
milliseconds = milliseconds % 1000;
if(milliseconds < 10)
milliseconds = "00" + milliseconds.toString();
else if(milliseconds < 100)
milliseconds = "0" + milliseconds.toString();
domAttr.set("milliseconds", "innerHTML", milliseconds + " milli");
},25); // updated time after every 25ms
} else {
this.set('label', 'Resume');
clearInterval(timeUpdate);
}
},
label: "Start"
}, "start_stop");
/*var resumeButton = new Button({
label: "Resume",
onClick: function(){
//clearInterval(timeUpdate);
//resetStopwatch();
}
}, "resume"); */
var resetButton = new Button({
label: "Reset",
onClick: function(){
domAttr.set("start", 'label', "Start");
clearInterval(timeUpdate);
resetStopwatch();
}
}, "reset");
});
function resetStopwatch(){
require(["dojo/dom-attr"], function(domAttr){
domAttr.set("hours", "innerHTML", "00 h ");
domAttr.set("minutes", "innerHTML", "00 m ");
domAttr.set("seconds", "innerHTML", "00 s ");
domAttr.set("milliseconds", "innerHTML", "000 milli");
});
}
function prependZero(time){
if(time < 10){
time = "0" + time.toString();
return time;
}
else
return time;
}
#stopwatch, #buttons{
text-align: center;
}
.claro *
{
outline: none;
}
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.9.1/dijit/themes/claro/claro.css">
<div id="stopwatch">
<span id="hours"></span>
<span id="minutes"></span>
<span id="seconds"></span>
<span id="milliseconds"></span>
</div>
<div id="buttons" class="claro">
<button id="start_stop"></button>
<!--<button id="resume"></button>-->
<button id="reset"></button>
</div>
Consider this use-case: click Start
> after some time, click Reset
- I plan to change the label from Stop
to Start
back again. So, I did:
domAttr.set("start", 'label', "Start"); // line # 83
But it is throwing an error:
Uncaught TypeError: Cannot call method 'setAttribute' of null
Not sure what I am doing wrong here. Please help!
Upvotes: 2
Views: 5149
Reputation: 44685
In Dojo there is a difference between widgets and DOM nodes. Your start button is a widget, so setting the label of that widget using a DOM node will not work. To change the label of the widget, you first need to retrieve the widget instance using the dijit/registry
module or by having a reference to your widget (ToggleButton
) already.
After that you can use the appropriate setter to change the label of the widget.
In your case the best thing to do is create a local reference to the new ToggleButton
, for example:
var startBtn = new ToggleButton({
/** Your code */
});
And then do the following:
startBtn.set("label", "Start");
As usual, I also updated your JSFiddle.
If you would like to use the dijit/registry
module (which isn't necessary now), you can get a reference to your widget using the widget ID (or the DOM ID) by using:
require(["dijit/registry"], function(registry) {
registry.byId("start_stop").set("label", "Start");
});
However, in this case it isn't useful, because you have an easier way of referencing your widget, but keep it in mind for future references (or if you start using declarative widgets).
Upvotes: 4
Reputation: 316
As the documentation states, you should pass a domNode into domAttr.set, not a string. So, instead of passing a string, "start", pass in a domNode (by using a data-dojo-attach-point for example).
I think you should replace it with "this.set('label', 'Start');".
This fixes your problem:
var startButton = new ToggleButton({
showLabel: true,
checked: false,
onChange: function(val) {
// code
},
label: "Start"
}, "start_stop");
var resetButton = new Button({
label: "Reset",
onClick: function(){
startButton.set('label', "Start");
clearInterval(timeUpdate);
resetStopwatch();
}
}, "reset");
});
Notice that i saved the reference to the startButton, so it can be references in the onClick from the resetButton.
Upvotes: 2