Search code examples
javascripthtmljquerymomentjscountdown

Multiple instances of countdown into html


I'm working a countdown with moment js. This is the code: https://telegra.ph/Codepen---Code-06-22 (CodePen)

I use this code to integrate into a programming table. This is the table: https://telegra.ph/Codepen---Code-06-22 (CodePen)

Now. What I really want to achieve is:

First. Have a separate code for each row in my table. (Perhaps one game is scheduled for 10:00, but another game could be scheduled for 10:15).

Second. Change the "if" condition so that the text displayed by my div changes if it has been more than 2 hours (which is what the games last approximately).

I am new to this so I appreciate any help.

Thanks-


Solution

  • You can achieve what you want with a two-step function:

    • The outer function will identify a DOM element into which the countdown will be written. The argument to this function must be a valid CSS selector.
    • The inner one will actually start the countdown to a given date. The argument(s) to this function will be passed on to the new Date() constructor called internally.

    The below snippet is merely a demonstration of the mechanics needed for such a reusable function. My outer function will also provide a "stop" button to make the countdown stop. Within each outer function you will have access to the setInterval()-handle t. You can utilise this to program any other stop-mechanism for it (involving clearInterval(t)).

    I was lazy when programming the time string inside the inner function: It will work correctly as long as the target event is within 31 days in the future from the current datetime. If you want to use it for a more general case you will have to put a little more effort into it ...

    function countdown(DOMsel){
      let trgEL=document.querySelector(DOMsel);   // target DOM element
      if (trgEL) return function(){
        let trgDT=new Date(...arguments),         // target Date object
            btn=trgEL.nextElementSibling;         // STOP button
        let t=setInterval(function(){
             let now=new Date()
             if (trgDT-now<0) { 
               trgEL.innerHTML="<b>Game over, please insert coin!</b>";
               clearInterval(t); // stop the current countdown
             } else {
               let str=new Date(trgDT - now).toJSON(); // timer string
               trgEL.textContent=+str.substr(8,2)-1+':'+str.substr(11,8)
             }
             }, 1000);
        btn.innerHTML='<button> stop </button>';  // build stop button ...
        btn.onclick=function(){clearInterval(t);} // assign stop function to it
      } 
      else return function(){console.log('target DOM element not found.');};
    }
    var now=new Date();
    countdown('td:nth-child(3)')(now.setSeconds(now.getSeconds()+20));
    countdown('tr:nth-child(5) td:nth-child(3)')(2020,5,26,20,5,27);
    <table>
    <tr><td>1</td><td>some</td><td>target1</td><td>next cell</td></tr>
    <tr><td>2</td><td>table</td><td>with</td><td>various</td></tr>
    <tr><td>3</td><td>cells</td><td>in</td><td>it.</td></tr>
    <tr><td>4</td><td>d</td><td></td><td></td></tr>
    <tr><td>5</td><td>e</td><td>target2</td><td></td></tr>
    <tr><td>6</td><td>f</td><td></td><td></td></tr>
    <tr><td>7</td><td>g</td><td></td><td></td></tr>
    <tr><td>8</td><td>h</td><td></td><td></td></tr>
    </table>

    I used the new Date() constructor in the format (y,mon,d,min,sec) with mon being a 0-based index of months, therefore 5 indicates the 6th month: June. Interestingly, the d numbers work like normal calendar dates. But they may overshoot: if I had entered 31, then that would have become "1 July". Other formats are available, see here. Your input is always interpreted according to your local time zone, but the string we get from .toJSON() is always "Greenwich time". This seems weird at first, but is a great help when you are dealing with a global audience as they will all refer to the same clock automatically!

    Edit:

    I changed the target datetime of my first countdown such that it will always give you a 20 seconds window. After that a final message appears and he countdown stops.