localStorage not clearing when using setInterval() for JS timer - javascript

I am working on a personal project and I am making use of JS to implement a simple countdown timer. There are several requirements that need to be addressed:
- The timer starts when the page is loaded
- When the user wishes to leave the page, they are warned that their progress will be lost, hence, the timer is reset.
I am making use of localStorage to keep the remaining time, since every time the user submits a form that is on the page, the page is reloaded (I understand that it is better to use AJAX, but for the time being, I am trying to make it work properly as it is). You can see my code below:
var submit_form;
var timeLeft;
function startTimer(duration, content) {
var timer = duration, min, sec;
setInterval(function () {
if (--timer < 0) {
//redirect here;
submit_form = true;
localStorage.removeItem("remainingTime");
window.location.replace("some url");
} else {
min = parseInt(timer / 60, 10);
sec = parseInt(timer % 60, 10);
min = min < 10 ? "0" + min : min;
sec = sec < 10 ? "0" + sec : sec;
localStorage.setItem("remainingTime", timer);
console.log(timer);
content.textContent = min + ":" + sec;
}
}, 1000);
}
window.onload = function () {
submit_form = false;
console.log(submit_form);
if (localStorage.getItem("remainingTime")) {
timeLeft = localStorage.getItem("remainingTime");
} else {
timeLeft = 60;
}
var display = document.querySelector('#time');
startTimer(timeLeft, display);
};
window.onbeforeunload = function () {
if (submit_form != true) {
localStorage.removeItem("remainingTime");
window.localStorage.clear();
return "You will lose all your progress!/nAre you sure you want to quit?";
}
};
'submit_form' is used for controlling when 'onbeforeunload' gets triggered - When the user submits the form, it shouldn't trigger.
<button type="submit" name="submit" value="Search" id="search-button" onclick="submit_form = true;">Submit</button>
The issue that I am facing, which is killing me, is that sometimes when the user tries to leave the page, i.e. 'onbeforeunload' is triggered, the localStorage doesn't always clear. Therefore, when they come back to the page, the timer doesn't start from the beginning, but instead, from where they left off.
I have tried a few variations of the code above, and my best guess is that setInterval() might be the reason for localStorage not clearing every time.

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!

Reset variable in Javascript on execute?

I am using this function to auto-click a button after 15 seconds. The problem is the user doesn't leave the page after the option is run and it may be re-run again on the same page but the timer continues. In fact, the timer continues even if I do the action myself.
<script type="text/javascript">
time = 15;
interval = setInterval(function() {
time--;
document.getElementById('Label1').innerHTML = "You must choose in " + time + " seconds"
if (time == 0) {
// stop timer
clearInterval(interval);
// click
document.getElementById('thebutton').click();
}
}, 1000)
</script>
So this script should run the timer and "press" the "thebutton" in fifteen seconds and then the timer should stop counting and reset until run again. If the button is pressed manually before 15 seconds it should still reset.
<input type='submit' id='thebutton' value='Done'></input>
Hopefully this is clear. I am still new and learning.
Set a base time and then reset it to that.
<script type="text/javascript">
time = 15;
baseTime = 15;
interval = setInterval(function() {
time--;
document.getElementById('Label1').innerHTML = "You must choose in " + time + " seconds"
if (time == 0) {
// stop timer
clearInterval(interval);
// click
document.getElementById('thebutton').click();
time = baseTime;
return false;
}
}, 1000)
</script>
I had a look at the code and the most critical thing that I think you should look at is that the button has no "onclick" function.
This means that clicking the button does nothing because you have not put a function there that does something when you click it.
I wrote some code that I hope helps:
let time = 15;
const label = document.getElementById("Label1");
const button = document.getElementById("thebutton");
const getText = () => `You must choose in ${time} seconds`;
const interval = setInterval(() => {
time--;
label.innerHTML = getText();
if (time === 0) {
// stop timer
clearInterval(interval);
// click
button.click();
}
}, 1000);
const stopTime = () => {
clearInterval(interval);
time = 15;
label.innerHTML = getText();
};
And in your html something like this:
<input type='submit' id='thebutton' value='Done' onclick="stopTime()" />
Finally I made a small video where I walk through the code, it could be useful as well: https://youtu.be/ZYS9AcxO3d4
Have a great day!
If you only want the button to be clicked once after 15 seconds then you should use the setTimeout() function instead of setInterval().
Then if you do not want the auto-click to happen if the user clicks the button then you would need to add an onClick handler to your button that calls clearTimeout().
I assume you want the label updated as the seconds count down? And it's unclear how the timer is started. Check the below code and see if it does what you expect.
var time, interval;
function stopTimer() {
if (interval) {
clearInterval(interval);
interval = null;
}
time = 15;
}
function timerAction() {
$('#lblStatus').text("You must choose in " + time + " seconds");
if (time-- <= 0) {
stopTimer();
console.log("done!");
$("#btnStop").click();
}
}
function startTimer() {
stopTimer();
timerAction();
interval = setInterval(timerAction, 1000);
}
$("#btnStart").click(function() {
startTimer();
});
$("#btnStop").click(function() {
stopTimer();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span id=lblStatus></span>
<button id='btnStart'>Reset / Start</button>
<button id='btnStop'>Stop</button>
If you want to run only once, you can use setTimeout function
setTimeout(your code, 15000);

How can I automatically "click" a button when a timer counts down to "0"? (How do I call click on a button from code?)

I am preparing an exam page. I have a time counter and it counts back from 60 seconds down to 0. There is a button NEXT, I want to skip to the next question when the time ends for the question. When you select your answer through the radio buttons and click NEXT, the page redirects to the next question, but when the time is up, I want the BUTTON be clicked automatically in order to skip to the next question.
Here is my code for counter :
function startResetTimer() {
time = 60;
interval = setInterval(function() {
time--;
document.getElementById('Label1').innerHTML = "" + time + " seconds"
}, 1000)
}
The remaining time is shown on the label label1 and the name of my button is SubmitButton.
interval = setInterval(function() {
time--;
document.getElementById('Label1').innerHTML = "" + time + " seconds"
if (time == 0) {
// stop timer
clearInterval(interval);
// click
document.getElementById('thebutton').click();
}
}, 1000)
Here is a JSFiddle: https://jsfiddle.net/ddan/cmtqzwa7/

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/

setInterval javascript calls do not go away after ajax load

I'm using MVC with some partial rendering and ajax calls. In one of my result tables I have a field that is a timer.
The following code is on my partial view that is rendered every 30 seconds. One of the fields is an active timer that displays to the user:
<td><div id="#someID" class="nobutton"></div><script>setInterval(function () { startTimer('#startDateTime', '#someID') }, 500);</script></td>
This works great but after the ajax call is made to refresh the partial, the interval function is still calling the old IDs (someID) that are no longer there.
Here is the javascript for the timer:
<script type="text/javascript">
function startTime(dt, field){
var field = document.getElementById(field);
if (field == null)
return;
var rowTime = new Date(dt);
var rowTimems = rowTime.getTime(rowTime);
var currentTime = new Date();
var currentTimems = currentTime.getTime(currentTime);
var difference = currentTimems - rowTimems;
var hours = Math.floor(difference / 36e5),
minutes = Math.floor(difference % 36e5 / 60000),
seconds = Math.floor(difference % 60000 / 1000);
field.innerHTML = formatTime(hours) + ":" + formatTime(minutes) + ":" + formatTime(seconds);
</script>
And the call on the main page that refreshes the partial is pretty simple:
var t = setInterval(function () {
$.ajax({
url: "MYURL",
type: "GET",
cache: false,
success: function (data) {
$("#summary").html(data);
}
});
}, 30000);
Is there a way to kill the old timers? Why are they still running?
The reason that code is still executing is that the interval was never stopped. Try this in your partial instead. It will check if the previous interval timer is present and clear it.
<td><div id="#someID" class="nobutton"></div>
<script>
if( window.prtInt != void 0 ) clearInterval(window.prtInt);//void 0 means undefined
window.prtInt = setInterval(function () { startTimer('#startDateTime', '#someID') }, 500);
</script></td>
If you wish to clear out all the timers on the entire page (may have undesirable affects) then you may get the integer for a new timer, and loop up to that number clearing intervals that are still present.
<script>
function clrTimers(){
var clr = setTimeout(function(){},10);
for( var i = 0; i < clr; i++ ){
clearInterval(i);
}
}
</script>
If you wish to skip some, then you could include them with the continue keyword if you knew them. Such as
for( var i = 0; i < clr; i++ ){
if( i == t ) continue; //I believe t was your ajax interval variable
clearInterval(i);
}
setInterval(function () { startTimer('#startDateTime', '#someID') }, 500);
Will continue to execute with the same values until it is cleared with clearInterval(). In order to clear it you need to save it a var and feed that to the clearInterval() function.

Categories