2

This is my Script for time counter for exam.This code is working fine but when $time = 90 minutes then i want to output like this 1:30 minutes left instead of 90 minutes left.This code only give output in minutes so can anybody help ?

<script type="text/javascript">
var timeoutHandle;
function countdown(minutes) {
    var seconds = 60;
    var mins = minutes
    function tick() {
        var counter = document.getElementById("timer");
        var current_minutes = mins-1
        seconds--;
        counter.innerHTML =
            current_minutes.toString() + ":" + (seconds < 10 ? "0" : "") + String(seconds);
        if( seconds > 0 ) {
            timeoutHandle=setTimeout(tick, 1000);
        } else {
            if(mins > 1){
                
                setTimeout(function () { countdown(mins - 1); }, 1000); }
        }
    }
    tick();
}
countdown('<?php echo $time; ?>');
</script>

This is my blade html file:

    <div id="timer"></div>
alotropico
  • 1,904
  • 3
  • 16
  • 24

2 Answers2

1

Here is a way to do it.

This will show hours and minutes only if they are more than 0:

var timeoutHandle;

function secondsToTime(seconds){
  if(seconds < 60) {
    return seconds
  } else {
    if(seconds/60 < 60) {
      const mins = Math.floor(seconds/60)
      return `${mins}:${seconds-mins*60}`
    } else {
      const hours = Math.floor((seconds/60)/60)
      const mins = Math.floor(seconds/60 - hours*60)
      return `${hours}:${mins}:${seconds-mins*60-hours*60*60}`
    }
  }
}

function countdown(minutes) {
    var seconds = minutes * 60
    function tick() {
        var counter = document.getElementById("timer")
        seconds--
        
        counter.innerHTML = secondsToTime(seconds)
        
        if(seconds > 1) timeoutHandle=setTimeout(tick, 1000)
    }
    tick()
}
countdown(70)
<div id="timer"></div>
alotropico
  • 1,904
  • 3
  • 16
  • 24
  • You can use a much shorter way calling new Date(seconds * 1000).toISOString().substr(11, 8) instead of the custom secondsToTime function, but in such case you will get zeroes like this: 00:00:07. See this answer https://stackoverflow.com/a/25279340/2762800 – alotropico Sep 06 '20 at 10:02
  • This doesn't correctly pad the values, e.g. 1:8:1 instead of 1:08:01. – RobG Sep 07 '20 at 01:06
  • That's why I made the comment previous to yours my friend – alotropico Sep 07 '20 at 01:24
  • The answer should be in the answer, not the comments. Creating a Date to format time is not particularly efficient and fails for times over 24 hours (and occasionally over 23 or 25 hours where daylight saving is observed). – RobG Sep 07 '20 at 02:56
  • The answer is for the question made, time with no padding. I get your critique to the comment but in this question it was just a comment to keep researching – alotropico Sep 07 '20 at 04:08
1

You should consider using setInterval instead of setTimeout as you're making a counter. Your code may look like

<script type="text/javascript">
    var timeoutHandle;
    function countdown(minutes) {
        var mins = minutes;
        var seconds = mins * 60;
        function tick() {
            var counter = document.getElementById("timer");
            seconds--; 
            var hours = Math.floor(seconds / 3600);
            var tmp = seconds % 3600;
            var m = Math.floor(tmp / 60);
            var s = tmp % 60;

            var format = hours > 0 ? (hours + ":") : "";
            format += (m > 0 ? (m + ":") : "00:") + s.toString();
            counter.innerHTML = format;
        }
    
        var interval = setInterval(tick, 1000);
        if (seconds <= 0) clearInterval(interval);
    }

    countdown('<?php echo $time; ?>');
</script>
raphalg
  • 448
  • 3
  • 11
  • 1
    For a countdown, a function that calls itself using *setTimeout* and calculates the time to the next full interval for each delay is preferable to using *setInterval* and a fixed delay as the *setInterval* approach will slowly drift (as will *setTImeout* with a fixed delay per the OP). ;-) – RobG Sep 07 '20 at 01:04