sasori
sasori

Reputation: 5463

how to create a realtime countdown effect to the time left between a start and end time inside a table?

I have search the internet before asking this. But I never found any duplicate question nor answer in stackoverflow.

let's say I have a start time

5:00 AM

Then I have an end time

6:15 AM

given the start and end time above, how to make a countdown effect to the time remaining in between the start and end time. the out put I want is something like e.g

01:14:01

(that one above means, there's only 1 hour and 14 minutes left before the countdown hit the end time value) That output will be written to an inside one of the of each row of data inside the table...the row of table is unlimited

e.g

<table>
<tr>
    <td>blhblah</td>
    <td>THE OUTPUT GOES HERE</td>
    <td>start time</td>
    <td>end time</td>
</tr>
<tr>
    <td>blhblah</td>
    <td>THE OUTPUT GOES HERE</td>
    <td>start time</td>
    <td>end time</td>
</tr>
<tr>
    <td>blhblah</td>
    <td>THE OUTPUT GOES HERE</td>
    <td>start time</td>
    <td>end time</td>
</tr>
</table>

my code to get the start time and end time for each row is like this

$('td:nth-child(3)').each(function() {

    var start_time = $.trim($(this).closest("tr").find('td:eq(7)').text());
    var end_time = $.trim($(this).closest("tr").find('td:eq(8)').text());


     //THE OUTPUT COUNTDOWN SHOULD BE HERE
     $(this).closest("tr").find('td:eq(6)').text(OUTPUT HERE);
 });

Upvotes: 1

Views: 807

Answers (1)

Kuo-hsuan Hsu
Kuo-hsuan Hsu

Reputation: 687

Update VII

jQuery(document).ready(function($) {

   let startTime = new Date()      //this line means doing timespan calculation with System Clock 
   let elems = $('#timerTable tr')
   
   elems.each(function(index) {
     if(index !==0)
     {
        let endTime = $(this).children().eq(3).text()
        //$(this).children().eq(2).text(getStartTimeHours(startTime))  //delete this line
        
        createCountDownTimer(startTime,endTime,$(this).children().eq(1))
     }
   });

   function getStartTimeHours(d){
       let ampm
       let cHours
       let cMinutes = d.getMinutes()

       if(d.getHours()>11)
       {
         cHours = d.getHours()-12
         ampm = "PM"
       }
       else
       {
         cHours = d.getHours()
         ampm = "AM"
       }
       
       return cHours+":"+cMinutes+" "+ampm
   }
   
   function createCountDownTimer(startTime, endTime, elem)
   {
      //let tempSt = startTime
      let tempEt = endTime
   
      //use current Date as token
   
      let tempDate = new Date()
      let cYear = tempDate.getFullYear()
      let cMonth = Number(tempDate.getMonth()+1)
      let cDate = tempDate.getDate()
   
      //use current Date as token
   
      console.log(cYear+"-"+cMonth+"-"+cDate)
   
      //let sT = new Date(cYear+"-"+cMonth+"-"+cDate+" "+tempSt);
      let sT = startTime
      let eT = new Date(cYear+"-"+cMonth+"-"+cDate+" "+tempEt);
      let timeSpan
   
   
      //***************************************************************************
      // This section is for the situation of date acrossing, if startTime later then endTime, then assume that endTime means hour in tomorrow and startTime means hour of today.
      // If you want this function, then replace this line :
      
         timeSpan = eT.getTime()-sT.getTime()    
      
      // with follow section:
      
      
      //if(eT.getTime()-sT.getTime()<0)
      //{
      //   let newET = new Date(cYear+"-"+cMonth+"-"+cDate+" "+tempEt);
      //   timeSpan = (newET.getTime()-sT.getTime())+1000*60*60*24  
      //}
      //else
      //{
      //   timeSpan = eT.getTime()-sT.getTime()
      //}
      
      //***************************************************************************
       
      
       
        let myVar = setInterval(countDownTimer, 1000);
        
      function countDownTimer(){
   
        
        timeSpan = timeSpan-1000
        let hours = Math.floor(timeSpan /(1000*60*60))
        let minutes = Math.floor((timeSpan % (1000*60*60)) / (1000*60))
        let seconds = Math.floor(((timeSpan % (1000*60*60)) % (1000*60)) / 1000)
        let countDownOutput = hours+":"+minutes+":"+seconds
        
        if(timeSpan < 1000)   //if countdown equal 0 second, stop timer
        {
           elem.text("-")
           console.log("stop")
           clearInterval(myVar)
        }
        else
        {
           elem.text(countDownOutput)
        }    
      }
   } 
   
   
});
td {
 width:150px;
 text-align:left
}

th {
 width:150px;
 text-align:left
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <table id="timerTable">
     <tr>
       <th>FLIGHT (No.)</th><th>REMINDING TIME</th><th>ARRIVAL</th><th>DEPARTURE</th>
     </tr>
     <tr>
       <td>CM 106</td><td></td><td>default time</td><td>7:30 PM</td>
     </tr>
     <tr>
       <td>SL 6204</td><td></td><td>default time</td><td>5:30 PM</td>
     </tr>
     <tr>
       <td>KL 552</td><td></td><td>default time</td><td>2:03 PM</td>
     </tr>
  </table>
</div>

Update V

If you wanna show "-" when timer stop, then tune function countDownTimer():

  function countDownTimer(){

     //if(timeSpan < 2000)   //if countdown equal 0 second, stop timer
     //{
     //   console.log("stop")
     //   clearInterval(myVar)
     //}
     timeSpan = timeSpan-1000
     let hours = Math.floor(timeSpan /(1000*60*60))
     let minutes = Math.floor((timeSpan % (1000*60*60)) / (1000*60))
     let seconds = ((timeSpan % (1000*60*60)) % (1000*60)) / 1000
     let countDownOutput = hours+":"+minutes+":"+seconds
    //  $("#"+domID).text(countDownOutput)
    //if (isNaN(countDownOutput)) {
    //    elem.text('-');
    //} else {
    //    elem.text(countDownOutput);     
    //}
    if(timeSpan < 1000)   //if countdown equal 0 second, stop timer
    {
       elem.text('-');
       console.log("stop")
       clearInterval(myVar)
    }
    else
    {
      elem.text(countDownOutput);
    } 
   }

And beware parameters of function createCountDownTimer(startTime, endTime, elem):

  1. parameter elem should ref to only one Dom Element obj, not an array of Dom Element.

  2. parameter startTime and endTime shoud be string, and must be like : "10:45 PM", "10:45:00 PM", "22:45:00", otherwise it would crash. Pattern like "9 April 2020 10:45:00 PM" is also wrong.

Update IV

It's close to solve this question.

Your code

$('td:nth-child(3)').each(function() {

    var start_time = $.trim($(this).closest("tr").find('td:eq(7)').text());
    var end_time = $.trim($(this).closest("tr").find('td:eq(8)').text());


    //THE OUTPUT COUNTDOWN SHOULD BE HERE
    //$(this).closest("tr").find('td:eq(6)').text(OUTPUT HERE);
    // the line above shouldn't be called here, appending countdown output  should place inside setInterval.

    createCountDownTimer(start_time, end_time, $(this).closest("tr").find('td:eq(6)'))
    //No need to pass domID, but pass domElement
});

Then need to tune function to append to domElement, instead of domID:

function createCountDownTimer(startTime, endTime, domID)

alter to

function createCountDownTimer(startTime, endTime, domElement)

Then alter function countDownTimer() :

    function countDownTimer(){
    ....
    ....
    ....
       //$("#"+domID).text(countDownOutput)
       domElement.text(countDownOutput)
    }

Then it should work.

Update III

Append timer to table row, you could try code below:

Update II

answer question:

1 March 2011 just a temp token, in order to create Date Obj, then use two Date objs (sT, eT) to calculate timeSpan. So, the date isn't matter, you could use any date at any month and any year as token.

If you wannna use current Date as token, then check the code below, I have updated.

Update I

You could use time form : "1:00 PM" or "1:00:01 PM" or "13:00" or "13:00:01" , all work fine.

Update1: if endTime is smaller then startTime, such as endTime: 6:00 AM startTime: 11:00 PM, then assume that endTime means tomorrow 6:00 AM and startTime as today 11:00 PM.

Update2: Add countdown timer stop function. When countdown equal 0 seconds, stop timer.

You could try codes below :

jQuery(document).ready(function($) {

   let timeTableArray = [
      {  
         title:"Timer 1",
         start:"10:00 AM",
         end:"11:00 AM"
      },
      {
         title:"Timer 2",
         start:"9:00 PM",
         end:"1:00 AM"
      },
      {
         title:"Timer 3",
         start:"11:10:00 PM",
         end:"11:10:05 PM"
      }
   ]

   timeTableArray.forEach((timer,index)=>{
     $("#timerTable").append('<tr><td class="cell">'+timer.title+'</td><td class="cell"><span id="timer'+index+'"></span></td><td class="cell">'+timer.start+'</td><td class="cell">'+timer.end+'</td></tr>')
     
     createCountDownTimer(timer.start, timer.end, "timer"+index)
   
   })
   
   function createCountDownTimer(startTime, endTime, domID)
   {
   
      let tempSt = startTime
      let tempEt = endTime
   
      //use current Date as token
   
      let tempDate = new Date()
      let cYear = tempDate.getFullYear()
      let cMonth = Number(tempDate.getMonth()+1)
      let cDate = tempDate.getDate()
   
      //use current Date as token
   
      console.log(cYear+"-"+cMonth+"-"+cDate)
   
      let sT = new Date(cYear+"-"+cMonth+"-"+cDate+" "+tempSt);
      let eT = new Date(cYear+"-"+cMonth+"-"+cDate+" "+tempEt);
      let timeSpan
   
   
      if(eT.getTime()-sT.getTime()<0)
      {
         let newET = new Date(cYear+"-"+cMonth+"-"+cDate+" "+tempEt);
         timeSpan = (newET.getTime()-sT.getTime())+1000*60*60*24  
         //if startTime later then endTime, then assume that endTime means hour in tomorrow and startTime means hour of today.

      }
      else
      {
         timeSpan = eT.getTime()-sT.getTime()
      }
 
       
        let myVar = setInterval(countDownTimer, 1000);
        
      function countDownTimer(){
   
        if(timeSpan < 2000)   //if countdown equal 0 second, stop timer
        {
           console.log("stop")
           clearInterval(myVar)
        }
        timeSpan = timeSpan-1000
        let hours = Math.floor(timeSpan /(1000*60*60))
        let minutes = Math.floor((timeSpan % (1000*60*60)) / (1000*60))
        let seconds = ((timeSpan % (1000*60*60)) % (1000*60)) / 1000
        let countDownOutput = hours+":"+minutes+":"+seconds
        $("#"+domID).text(countDownOutput)
      }
   } 
   
});
.cell {
 width:150px

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <table id="timerTable">
  </table>
</div>

Upvotes: 0

Related Questions