0

I have this code which lets me count down my races to the start time.

How ever they are all showing the same countdown time.

Each row has its own matching ID.

Question How to make sure that the countdown timer works for each row and not the same time

enter image description here

<div class="container">
    <div class="row">
        <div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
            <div class="card">
            <div class="card-header">
            Featured
            </div>
            <div class="card-body">
                <table class="table table-striped table-bordered">
                    <tbody id="upandcoming">
                        <?php foreach ($races as $race) {?>
                            <tr>
                                <td></td>
                                <td><b>M<?php echo $race['meeting_number'];?></b></td>
                                <td><b>R<?php echo $race['racing_number'];?></b></td>
                                <td><b><?php echo $race['meeting_name'];?></b></td>
                                <td><div id="race<?php echo $race['race_id'];?>"></div>                             

                                </td>
                            </tr>

                        <?php }?>
                    </tbody>
                </table>
            </div>
            </div>
        </div>
    </div>
</div>

<?php foreach ($races as $race) {?>
<script>
// Set the date we're counting down to
var countDownDate = new Date("<?php echo date('M j, Y H:i:s', strtotime($race['racing_datetime']));?>").getTime();

// Update the count down every 1 second
var x = setInterval(function() {

// Get todays date and time
var now = new Date().getTime();

// Find the distance between now an the count down date
var distance = countDownDate - now;

// Time calculations for days, hours, minutes and seconds
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);

// Output the result in an element with id="demo"
document.getElementById("race<?php echo $race['race_id'];?>").innerHTML =  hours + "h "
+ minutes + "m " + seconds + "s "; 

// If the count down is over, write some text 
if (distance < 0) {
    clearInterval(x);
        document.getElementById("race<?php echo $race['race_id'];?>").innerHTML = "EXPIRED";
    }
}, 1000);
</script>   
<?php }?>
1
  • What are the values of countDownDate, I would like to check it. Commented Mar 2, 2018 at 6:57

1 Answer 1

1

By printing out multiple script tags, you are redefining countDownDate in the global scope over and over again, overwriting the value of the previous copies. The value all of your counters are using is the last value that was set.

Outputting multiple script tags with the code repeated, not to mention creating a timer for each of them, is very inefficient. Instead, I would suggest you output the information as an array and have one timer loop over that array to create all of the countdowns.

<script>
// Set the date we're counting down to
var countdowns = [
<?php foreach ($races as $race) {?>
  {
    id: <?php $race['race_id'] ?>,
    date: new Date("<?php echo date('M j, Y H:i:s', strtotime($race['racing_datetime']));?>").getTime()
  }
<?php }?>
];

// Update the count down every 1 second
var timer = setInterval(function() {
  // Get todays date and time
  var now = Date.now();

  var index = countdowns.length - 1;

  // we have to loop backwards since we will be removing
  // countdowns when they are finished
  while(index >= 0) {
    var countdown = countdowns[index];

    // Find the distance between now and the count down date
    var distance = countdown.date - now;

    // Time calculations for days, hours, minutes and seconds
    var days = Math.floor(distance / (1000 * 60 * 60 * 24));
    var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
    var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
    var seconds = Math.floor((distance % (1000 * 60)) / 1000);

    var timerElement = document.getElementById("race" + countdown.id);

    // If the count down is over, write some text 
    if (distance < 0) {
      timerElement.innerHTML = "EXPIRED";
      // this timer is done, remove it
      countdowns.splice(index, 1);
    } else {
      timerElement.innerHTML =  hours + "h " + minutes + "m " + seconds + "s "; 
    }

    index -= 1;
  }

  // if all countdowns have finished, stop timer
  if (countdowns.length < 1) {
    clearInterval(timer);
  }
}, 1000);
</script>  
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

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