I am using simple svg count down timer (Credits: Mateusz Rybczonec)
I want to modify the code below as:
- On change of Select dropdown option Timer value and Timer has to reset
Tried with below code with no luck :(
First time select it is working fine, after re-selecting different value, both values coming inside circle.
HTML:
<select id="settings-select-popup-autoclose">
<option value="-- Select --" selected="selected">-- Select --</option>
<option value="5">5 seconds</option>
<option value="10">10 seconds</option>
<option value="15">15 seconds</option>
<option value="20">20 seconds</option>
<option value="25">25 seconds</option>
<option value="30">30 seconds</option>
<option value="35">25 seconds</option>
<option value="40">40 seconds</option>
<option value="45">45 seconds</option>
<option value="50">50 seconds</option>
<option value="55">55 seconds</option>
<option value="60">60 seconds</option>
</select>
<div id="popupAutoCloseText"></div>
JS code:
// Credit: Mateusz Rybczonec
jQuery(document).on('change', '#settings-select-popup-autoclose', function (e) {
jQuery('#popupAutoCloseText #app').remove();
var __selected_time = jQuery(this).find('option:selected').val();
const FULL_DASH_ARRAY = 283;
const WARNING_THRESHOLD = 10;
const ALERT_THRESHOLD = 5;
const COLOR_CODES = {
info: {
color: "green"
},
warning: {
color: "orange",
threshold: WARNING_THRESHOLD
},
alert: {
color: "red",
threshold: ALERT_THRESHOLD
}
};
const TIME_LIMIT = __selected_time;
let timePassed = 0;
let timeLeft = TIME_LIMIT;
let timerInterval = null;
let remainingPathColor = COLOR_CODES.info.color;
jQuery('#popupAutoCloseText').append(`
<div id="app">
<div id="popupAutoCloseText">
<span >Popup closes in </span>
<span >
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><g ><circle cx="50" cy="50" r="45"></circle><path id="base-timer-path-remaining" stroke-dasharray="283" d=" M 50, 50 m -45, 0 a 45,45 0 1,0 90,0 a 45,45 0 1,0 -90,0"></path></g></svg>
<span id="base-timer-label" >${formatTime(timeLeft)}</span>
</span>
<span >seconds</span>
</div>
</div>
`);
startTimer();
function onTimesUp() {
clearInterval(timerInterval);
}
function startTimer() {
timerInterval = setInterval(() => {
timePassed = timePassed = 1;
timeLeft = TIME_LIMIT - timePassed;
document.getElementById("base-timer-label").innerHTML = formatTime(
timeLeft
);
setCircleDasharray();
setRemainingPathColor(timeLeft);
if (timeLeft === 0) {
onTimesUp();
}
}, 1000);
}
function formatTime(time) {
const minutes = Math.floor(time / 60);
let seconds = time % 60;
if (seconds < 10) {
seconds = `0${seconds}`;
}
//return `${minutes}:${seconds}`;
return `${seconds}`;
}
function setRemainingPathColor(timeLeft) {
const { alert, warning, info } = COLOR_CODES;
if (timeLeft <= alert.threshold) {
document
.getElementById("base-timer-path-remaining")
.classList.remove(warning.color);
document
.getElementById("base-timer-path-remaining")
.classList.add(alert.color);
} else if (timeLeft <= warning.threshold) {
document
.getElementById("base-timer-path-remaining")
.classList.remove(info.color);
document
.getElementById("base-timer-path-remaining")
.classList.add(warning.color);
}
}
function calculateTimeFraction() {
const rawTimeFraction = timeLeft / TIME_LIMIT;
return rawTimeFraction - (1 / TIME_LIMIT) * (1 - rawTimeFraction);
}
function setCircleDasharray() {
const circleDasharray = `${(
calculateTimeFraction() * FULL_DASH_ARRAY
).toFixed(0)} 283`;
document
.getElementById("base-timer-path-remaining")
.setAttribute("stroke-dasharray", circleDasharray);
}
});
CodePudding user response:
Well you need to clear the setInterval every time you change the selection at drop down. The easiest to do this is declaring a variable for interval
Declare this at the very top outside of .onChange scope
var inter = null;
It is important to clear it before starting the timer
if(inter){
clearInterval(inter);
}
inter = startTimer();
Lastly return the timeInterval at your startTimer
function
function startTimer() {
timerInterval = setInterval(() => {
timePassed = timePassed = 1;
timeLeft = TIME_LIMIT - timePassed;
document.getElementById("base-timer-label").innerHTML = formatTime(
timeLeft
);
setCircleDasharray();
setRemainingPathColor(timeLeft);
if (timeLeft === 0) {
onTimesUp();
}
}, 1000);
return timerInterval;
}
See the working example here https://jsfiddle.net/npvL7kcf/2/