Search code examples
javascriptjqueryhtmlruby-on-railscountdown

countdown timer on list giving the same timer results for each list item rails


Im trying to create a countdown timer and for some reason the class inst making each of these countdowns unique. All of my countdowns are the same eventhough they all are different due_dates.

  • in my console.log(reservation.duedate) i get different due_dates which is correct and what it is suppose to be.

  • the countdown is using the first result of due_date for each of the lists in the countdown function in js. This is not correct; each countdown must be separate for each list item.

what it looks like

This is in your_essays method in reservations_controller:

@reservations_pending = user.reservations.where("turned_in = ?", false).where("completed = ?", false).where("due_date >= ?", DateTime.now).order(created_at: :desc).page(params[:page_pending]).per_page(3)

your_essays.html.erb:

<div id="content-load-more-pending">
 <%= render 'your_essays_pending', reservations_pending: @reservations_pending %>
</div>

This is the partial within your_essays.html.erb called _your_essays_completed.html.erb

<% reservations_pending.each do |reservation| %>

<div style="color:blue;" class="countdown-class"></div>
<script type="text/javascript">
$(".countdown-class")
.countdown("<%= reservation.due_date %>", function(event) {
$(this).text(
event.strftime('%D days %H:%M:%S')
);
});

console.log("<%= reservation.due_date %>");
</script> 

<% end %>

here is console.log(event) and console.log("<%= reservation.due_date %>"); enter image description here


Solution

  • Each time you go through the loop, you're resetting every instance of .countdown-class to the new due date. That should explain why they're all taking on the value of the last one.

    There's a couple of ways to fix this. You could use the id of each reservation and add it to the class name, for example. This gives you uniques classes, and allows each successive change to not affect previous ones.

    You could also streamline the code by doing something like:

    <% reservations_pending.each do |reservation| %>
      <div style="color:blue;" class="countdown-class" data-due-date="<%= reservation.due_date %>"></div>
    <% end %>
    
    <script type="text/javascript">
      $(".countdown-class").each(function() {
        $(this).countdown($(this).data("due-date"), function(event) {
          $(this).text(event.strftime('%D days %H:%M:%S'));
        });
      });
    </script> 
    

    By "storing" the due date inside a data attribute on the div itself, you're able to eliminate the repetition of the JS code.

    Edit: here's a working example https://jsfiddle.net/3j368s46/