angular timer - .stop() and .resume() problems - javascript

I'm having a bit trouble with my timer. I might have made it more complicated than it should be because what I need is the following:
I need to count from 00:00 to say 45:00 and I need to be able to stop and resume the timer within these boundaries.
Right now I've got this timer code:
<timer id="timer" autostart="false" start-time="coutingStart" end-time="countingEnd">{{mminutes}}:{{sseconds}}</timer>
countingStart and countingEnd initializes like this:
var time = (45 * 60000); // should give me 45 minutes of time.
$scope.countingStart = (new Date()).getTime();
$scope.countingEnd = (new Date()).getTime() + time;
This code above works, atleast I think it does.
I've got a button with this function on it:
$scope.startGame = function() {
$scope.gameIsLive = true;
document.getElementById('timer').start();
};
which starts my counter, no problem, it starts from 00:00 atleast.
But then I have buttons with these functions aswell which is where I'm having my problem.
$scope.PauseGame = function() {
switch ($scope.periodNum) {
case 1:
document.getElementById('timer').stop();
$scope.PauseIsActive = true;
break;
case 2:
document.getElementById('timer').stop();
$scope.PauseIsActive = true;
break;
}
};
$scope.ResumeGame = function() {
switch ($scope.periodNum) {
case 1:
document.getElementById('timer').resume();
$scope.PauseIsActive = false;
break;
case 2:
document.getElementById('timer').resume();
$scope.PauseIsActive = false;
break;
}
};
Both pauseGame() and resumeGame() works as expected. They are pausing and resuming the timer. But, when I pause the timer on say 00:10 and count for myself 10 seconds and then resume it the timer now stands on 00:20 which made me just lost 10 seconds of the timer.
I can think that my problem is inside the instantiating of $scope.counterStart and $scope.counterEnd. But I am not sure. How can I count from 00:00 to 45:00 and still being able to stop and resume the clock when needed?
Angular timer uses the Date object and milliseconds to count time so I suppose I have to use this approach to get 00:00 which is now and count 45 minutes forward. Can it be done otherwise with stop and resume functionality?
Thanks.

If I understand the angular-timer docs end-time sets the countdown time. It doesn't provide a maximum value.
end-time Sets the countdown based on predefined end time (in
milliseconds).
To have a maximum value you can check each tick event to see if the configured maximum value has been reached. I have created an example below in which the timer is stopped when it reaches the maximum value (10 seconds).
(function() {
angular
.module('exampleApp', ['timer'])
.controller('ExampleController', ExampleController);
function ExampleController($scope, TimerStatusEnum, $timeout) {
var vm = this;
vm.max = 10000; // 10 seconds
vm.isMaxReached = false;
vm.timerStatus = TimerStatusEnum.NotStarted;
vm.startTimer = function() {
if (!vm.isMaxReached) {
if (vm.timerStatus === TimerStatusEnum.NotStarted) {
$scope.$broadcast('timer-start');
vm.timerStatus = TimerStatusEnum.Running
} else if (vm.timerStatus === TimerStatusEnum.Stopped) {
$scope.$broadcast('timer-resume');
vm.timerStatus = TimerStatusEnum.Running
}
}
};
vm.stopTimer = function() {
if (vm.timerStatus === TimerStatusEnum.Running) {
$scope.$broadcast('timer-stop');
vm.timerStatus = TimerStatusEnum.Stopped
}
};
vm.isTimerStopped = function() {
return vm.timerStatus === TimerStatusEnum.Stopped;
}
vm.isTimerRunning = function() {
return vm.timerStatus === TimerStatusEnum.Running;
}
$scope.$on('timer-tick', function(event, args) {
var roundedMiliSecondCount = Math.round(args.millis / 1000) * 1000;
if (roundedMiliSecondCount === vm.max) {
$timeout(function() {
vm.isMaxReached = true;
vm.stopTimer();
}, 0);
}
});
}
ExampleController.$inject = ['$scope', 'TimerStatusEnum', '$timeout'];
})();
(function() {
angular
.module('exampleApp')
.constant('TimerStatusEnum', {
'NotStarted': 0,
'Stopped': 1,
'Running': 2
});
})();
<!DOCTYPE html>
<html ng-app='exampleApp'>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-timer/1.3.4/angular-timer.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/humanize-duration/3.9.1/humanize-duration.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.14.1/moment.min.js"></script>
</head>
<body ng-controller="ExampleController as vm">
<timer id="timer" autostart="false" interval="1000">{{mminutes}}:{{sseconds}}</timer>
<button ng-click="vm.startTimer()" ng-disabled="vm.isTimerRunning() || vm.isMaxReached">Start Timer</button>
<button ng-click="vm.stopTimer()" ng-disabled="vm.isTimerStopped() || vm.isMaxReached">Stop Timer</button>
<p ng-if="vm.isMaxReached">Max time has been reached</p>
</body>
</html>

Related

Set a background timer in javascript

I'm trying to prevent users in Dynamics 365 / CRM from quickly clicking on the same button, thus initiating a synchronous, window-blocking event.
We were able to fix this in IE, but Chrome seems to "remember" the button clicks - and then initiate the same event, again and again, synchronously (as is expected).
I had thought about creating a background timer, that will be initiated on the first button click, which will turn a variable as 'True' until the timer finishes, then turning the variable as 'False'.
During those X seconds in which the variable is set to true, subsequent button clicks will fire the event, but not proceed any further than a few lines where the function will check if the variable is set to true or false.
This is my (not working) code so far:
function startTimer(duration) {
isTimerOn = true;
var timer = duration, seconds;
setInterval (function () {
seconds = parseInt(timer % 60, 10);
seconds = seconds < 10 ? 0 + seconds : seconds;
if (--timer < 0) {
timer = duration;
}
}, 500);
isTimerOn = false;
};
var isTimerOn = false;
function createWordSummary() {
if (isTimerOn) {
return;
}
try {
startTimer(3);
// Logic here
Would love some help, thanks in advance!
You can try something like this:
let disabled = false;
function startTimer(s) {
disabled = true;
setTimeout(function() {
disabled = false;
}, s * 1000);
}
function createWordSummary() {
if ( disabled ) return;
startTimer(3);
console.log('check');
}
<button onclick="createWordSummary()">Check</button>
Hope it helps!

Chrome Extensions: Javascript not not running clearInterval();

I'm trying the make a chrome extension in javascript. So far, my popup.js looks like this:
let bg;
let clock;
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('button1').addEventListener('click', butClicked);
bg = chrome.extension.getBackgroundPage();
//clock = document.getElementById("label1");
});
let timeStamp;
let isClockRunning = false;
function butClicked() {
let test = bg.getURL();
document.getElementById('test').innerHTML = test;
timeStamp = new Date();
isClockRunning = !isClockRunning;
runCheckTimer();
}
function runCheckTimer() {
var handle;
if(isClockRunning == true) {
handle = setInterval(updateClock, 1000);
}
else if(isClockRunning == false) {
clearInterval(handle);
handle = 0;
}
}
function updateClock() {
let seconds = bg.returnTimeSince(timeStamp);
document.getElementById("label1").innerHTML = "Seconds: " + seconds;
}
The program works just fine when I click the button once; it starts the timer. But when I click the button the second time, timeStamp gets set to 0, but the updateClock keeps running at the same interval; the interval doesn't get cleared even though I'm toggling the isClockRunning boolean. It's almost as if javascript is forgetting to run the else if part in runCheckTimer(). How can I fix this?
EDIT: On a sidenote, am I doing the timer thing the right way? Or is there a better way to do it? I basically want a timer to keep ticking every second since you've pressed the button, and then when you click it again it'll stop and reset to 0.
You have scoped handle to runCheckTimer. When runCheckTimer starts, it will create a new handle every time.
Move handle outside of the function.
var handle;
function runCheckTimer() {
if(isClockRunning == true) {
handle = setInterval(updateClock, 1000);
}
else if(isClockRunning == false) {
clearInterval(handle);
handle = 0;
}
}

AngularJS $interval displays timer (when the interval will elapse)

Hi am new to Angular am using $interval to call a function periodically and i want to display a timer in the screen when the next function call will happen , a countdown to the next call . is there anyway simple way to do within this function .
function init(){
$scope.interval = $interval(function(){
$scope.loading = true;
//$scope.countdown = countdown to next call;
doSomework();
}, 60000);
}
Any suggestions are welcome .Thanks in advance
function init(){
var remainingTime = 60;
var interval = $interval(function(){
$scope.loading = true;
remainingTime = remainingTime - 1;
$scope.showRemainingTIme = remainingTime; // Use this variable to show on the view page
if(remainingTime == 0) {
$interval.cancel(interval);
doSomework();
}
}, 1000);
}
Here is what you need. The second argument in $interval is the time after which you want the function to execute and its in miliseconds so 1000ms=1sec.
So after every second it will reduce thhe value of $scope.remainingTimeby 1. You can have the value according to your requirement. Just for demo i have considered it to be 60 and the interval to be 1sec so after every second the $scope.remainingTimewill be decremented by 1
angular.module('timerApp', []);
angular.module('timerApp').controller('timerController', ['$scope', '$interval', function ($scope, $interval) {
$scope.remainingTime = 60;
$scope.timeInterval=$interval(function(){
$scope.remainingTime = $scope.remainingTime - 1;
if($scope.remainingTime==0){
//$interval.cancel($scope.timeInterval);
$scope.remainingTime=60;
}
}, 1000);
}]);
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>
<body>
<div ng-app="timerApp" ng-controller="timerController">
<div >{{remainingTime}}</div>
</div>
</body>

Javascript Countdown that loads ahref

I'm totally a beginner with JavaScript and I'm trying to make a Javascript Countdown that loads an
I'm using this code for the countdown
<script language="Javascript">
var countdown;
var countdown_number;
function countdown_init() {
countdown_number = 11;
countdown_trigger();
}
function countdown_trigger() {
if(countdown_number > 0) {
countdown_number--;
document.getElementById('countdown_text').innerHTML = countdown_number;
if(countdown_number > 0) {
countdown = setTimeout('countdown_trigger()', 1000);
}
}
}
function countdown_clear() {
clearTimeout(countdown);
}
</script>
I want to load exactly this after the count reaches 0... I am totally lost... what should I do?
It is basically a countdown that stops a music player after reaching 0. I would like to set up several countdowns with 10 mins, 15 mins, and 30 mins.
var countdown;
var countdown_number;
function countdown_init(time) {
countdown_number = time;
countdown_trigger();
}
function countdown_trigger() {
if (countdown_number > 0) {
countdown_number--;
document.getElementById('countdown_text').innerHTML = countdown_number;
setTimeout('countdown_trigger()', 1000)
} else { // when reach 0sec
stop_music()
}
}
function stop_music(){
window.location.href = "bgplayer-stop://"; //will redirect you automatically
}
Here is a simple example using mostly what you had above. This will need to be expanded a bit in order to have multiple countdowns but the general idea is here.
Fiddle: http://jsfiddle.net/zp6nfc9b/5/
HTML:
<a id="link_to_click" href="bgplayer-stop://">link</a>
<span id="countdown_text"></span>
JS:
var countdown_number;
var countdown_text = document.getElementById('countdown_text');
var link_to_click = document.getElementById('link_to_click');
function countdown_init() {
countdown_number = 11;
countdown_trigger();
}
function countdown_trigger() {
countdown_number--;
countdown_text.innerHTML = countdown_number;
if (countdown_number > 0) {
setTimeout(
function () {
countdown_trigger();
}, 1000
);
}
else {
link_to_click.click();
}
}
link_to_click.addEventListener('click',
function () {
countdown_text.innerHTML = 'link was clicked after countdown';
}
);
countdown_init();
To explain some portions a little I think overall you had the correct idea.
I only added the eventListener so you could see the link was actually being clicked and displays a message in the countdown_text for you.
You didn't need to check countdown_number more than once so I removed that if block.
Also you don't really need to clear the timeout either. It clears itself once it executes. You only really need to clear a timeout if you want to stop it before it completes but since we rely on the timeout completing in order to do the next step its not necessary.

Timer for Slideshow does nothing

Sorry for that short and meaningless title, but it really is the only one that really describes my problem.
I want (or have to) script a slideshow which (if a checkbox is checked and a time is given) automatically switches the focus on another image.
I already have everything but the automation and am currently working on it.
I thought that comparing the current time with a target time (currentTime + user-input seconds (in Integer)) every 1000 millisecs would be the best way to do it.
However, I don't get why, but it's not working. The calculated target time seems to be correct, since I get a correct difference of the pre-calculated date.getTime() and the calculated one.
I would be very thankful if you could help me.
Here's the JS:
var checkbox_checked;
function timerfn() {
if (checkbox_checked === null || checkbox_checked === false) {
checkbox_checked = true;
var targetTime = new Date();
alert(targetTime.getTime());
var target_sec = targetTime.getSeconds() + dauerSwitch;
targetTime.setSeconds(target_sec);
alert(targetTime.getTime());
// update currentTime every 1 Seconds (1000 Milliseconds)
setInterval(function () {
var current_time = Date.now();
if (targetTime.getTime() == current_time) {
gallery("zur");
}
}, 1000);
} else {
checkbox_checked = false;
}
}
And here's the HTML:
<form>
<input type="checkbox" id="timer" name="timer" onClick="timerfn()">
<input type="text" id="textbox" name="timerParam"
placeholder="Seconds between slides" value=""
onBlur="boxConv()"> //boxConv just converts the String to an Integer. It also checks if it's only numbers
</form>
Thats how i would do it with a little help of jquery ($). I moved the inline code into JS event listener and used the user input as parameter for the interval to make it work.
$(function () {
var intervalTime = 1000,
counter = 1,
interval;
$("#textbox").on("blur", function () {
var inputValue = $(this).val();
try {
//parses the user input into a integer
intervalTime = parseInt(inputValue, 10) * 1000;
} catch (e) {
//could not parse input
}
});
$("#timer").on("click", function () {
if ($(this).is(":checked")) {
interval = setInterval(function () {
//gallery("zur");
//fills the test output
$("#testOutput").val(counter);
counter++;
}, intervalTime); //intervall time is given in milliseconds
} else {
clearInterval(interval);
}
});
});
And here the link to a working example:
http://jsfiddle.net/9Yeuh/2/

Categories