Home > OS >  :: jQuery :: OnChange update timer count down
:: jQuery :: OnChange update timer count down

Time:12-29

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.

enter image description here

jsFiddle

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/

  • Related