0

I have attempted using the for loop to display my Countdown, but I don't know where I am getting it wrong. Is there a simpler way to display the countdown for each row using vanilla javascript?

My Table Below:

var exp = document.getElementById('tab').getElementsByClassName('exp1');
    
    var x = document.getElementById('tab').getElementsByClassName('demo');
    
    var   now = new Date();
    function test(){
    
    for (i = 0; i<exp.length; i++){
    var  e = new Date( exp[i].innerHTML);
    var  timeDiff = e.getTime() - now.getTime();
    var seconds = Math.floor(timeDiff / 1000);
    var minutes = Math.floor(seconds / 60);
    var hours   = Math.floor(minutes / 60);
    var days    = Math.floor(hours   / 24);
    hours %=24;
    minutes %=60;
    seconds %=60;
    var timer = setTimeout('test()', 1000);   
    }
    
    for (i=0; i<x.length; i++){
    x[i].innerHTML = days  + " " +  hours + " " + minutes + " " + seconds;
    }
    }
    <html>
    <body> 
    <table style="width:50%" id= "tab">
    <tr>
    <th>Name</th>
    <th>Exp</th>
    <th>Count Down</th>
    </tr>
        <tr>
         <td> A</td>
         <td class = 'exp1'> 09/08/2019</td>
         <td class = 'demo'> </td>   
        </tr>
        <tr>
         <td> B</td>
         <td class = 'exp1'> 09/08/2020</td>
         <td class = 'demo'> </td>   
        </tr>
    </table>
    </body>
    </html>

3
  • Here's a pretty good example of what you're trying to accomplish link Commented Oct 11, 2018 at 11:35
  • change var timer = setTimeout('test()', 1000); to var timer = setTimeout(test, 1000); Commented Oct 11, 2018 at 11:35
  • setTimeout(test, 1000) pass the function, not the result of calling the function Commented Oct 11, 2018 at 11:38

2 Answers 2

2

In your code, there's no first time call to test(). So either you forgot to write it in the question or you don't have it in the code. Someone needs to call test() for the first time before that forever loop with setTimeout begins.

I have added a snippet of code that you can run, it has the HTML you pasted as well as the JavaScript. The only difference is that I called test() after your var now to get it started.

A couple of things:

  • I moved the setTimeout out of the for loop since putting it there would mean that you'd call it with every iteration instead of every second. Also, you can't have the now variable as a global value, you need to get it every time you want to calculate the difference inside the function. If you look into the docs you'll see:

Creates a JavaScript Date instance that represents a single moment in time. Date objects are based on a time value that is the number of milliseconds since 1 January 1970 UTC. var date1 = new Date('December 17, 1995 03:24:00'); // Sun Dec 17 1995 03:24:00 GMT...

That means that when you create the Date, it represents a single moment in time, it's like if you took a snapshot of that time and kept it there, frozen.

  • The second problem comes with how you are displaying the info. If you have variables that you are changing within that for loop scope, once you leave that iteration, the values are gone forever. If you only display that info (days, minutes, hours, days) after your for loop, then you will have the last value saved into those variables. Not exactly what you are looking for. To fix that all you have to do is move that x[i].innerHTML = days + " days " + hours + " hours " + minutes + " minutes " + seconds + " seconds"; to the same loop as where you are calculating the values.
  • As a side note, you could checkout setInterval() since it's pretty much what you want.

var exp = document.getElementById('tab').getElementsByClassName('exp1');
var x = document.getElementById('tab').getElementsByClassName('demo');
test();

function test() {
  var now = new Date();
  for (i = 0; i < exp.length; i++) {
    var e = new Date(exp[i].innerHTML);
    var timeDiff = e.getTime() - now.getTime();
    var seconds = Math.floor(timeDiff / 1000);
    var minutes = Math.floor(seconds / 60);
    var hours = Math.floor(minutes / 60);
    var days = Math.floor(hours / 24);
    hours %= 24;
    minutes %= 60;
    seconds %= 60;
    x[i].innerHTML = days + " days " + hours + " hours " + minutes + " minutes " + seconds + " seconds";
  }

  var timer = setTimeout("test()", 1000);
}
<html>

<body>
  <table style="width:50%" id="tab">
    <tr>
      <th>Name</th>
      <th>Exp</th>
      <th>Count Down</th>
    </tr>
    <tr>
      <td> A</td>
      <td class='exp1'> 09/08/2019</td>
      <td class='demo'> </td>
    </tr>
    <tr>
      <td> B</td>
      <td class='exp1'> 09/08/2020</td>
      <td class='demo'> </td>
    </tr>
  </table>
</body>

</html>

Sign up to request clarification or add additional context in comments.

Comments

1

You have done most of the things right.. using setInterval and a minor modification will make this work

var exp = document.getElementById('tab').getElementsByClassName('exp1');

var x = document.getElementById('tab').getElementsByClassName('demo');


function test(){
  var   now = new Date();
  for (i = 0; i<exp.length; i++){
    var  e = new Date( exp[i].innerHTML);
    var  timeDiff = e.getTime() - now.getTime();
    var seconds = Math.floor(timeDiff / 1000);
    var minutes = Math.floor(seconds / 60);
    var hours   = Math.floor(minutes / 60);
    var days    = Math.floor(hours   / 24);
    hours %=24;
    minutes %=60;
    seconds %=60;
    x[i].innerHTML =  days  + "d " +  hours + "h " + minutes + "m " + seconds +"s";
  //var timer = setTimeout('test()', 1000);   
  }

  //for (i=0; i<x.length; i++){
  //x[i].innerHTML = days  + " " +  hours + " " + minutes + " " + seconds;
  //}
}
setInterval(function(){ test();; }, 1000);
<html>
<body> 
<table style="width:100%" id= "tab">
<tr>
<th>Name</th>
<th>Exp</th>
<th>Count Down</th>
</tr>
    <tr>
     <td> A</td>
     <td class = 'exp1'> 10/13/2018</td>
     <td class = 'demo'> </td>   
    </tr>
    <tr>
     <td> B</td>
     <td class = 'exp1'> 09/08/2020</td>
     <td class = 'demo'> </td>   
    </tr>
</table>
</body>
</html>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.