tags:

views:

73

answers:

2

Firstly, how can I have jQuery continuously check the time, and add an id to a <div> tag if the current time is in between two set times? I'm making a clock for a school (where the clock is a website sent over cable to TVs in every room), where each period is expressed like this:

<div class="period 1">Period 1: 7:32-8:14</div>

I'm getting the start time and end time from DataMapper, so really, the code in the view (an eRB file) is:

<% @periods.each do |@period| %>
<div class="period <%= @period.id %>"><%= @period.string %>: <%= @period.start_time.strftime("%I:%M") %>&ndash;<%= @period.end_time.strftime("%I:%M") %></div>
<% end %>

My question is how I can get jQuery to continuously check the current time, and if it is in between @period.start_time and @period.end_time. If so, add id="active" to the <div>.

Would I have to set up something for JavaScript to interface with Ruby via .get?

If you have any questions, please ask.

+3  A: 

You can acheive this using Javascript's Date() object. Revision due to clarification of question

CSS

.active { font-weight: bold; } // Or whatever styling you need

Javascript

var loop = setInterval(function() {
  var d = new Date();
  var dh = d.getHours();
  var cP = 16; 
  /* make cP your earliest period
  earlier than 1600, but that's for it to
  work with the current time for me (8pm) 
  each pass with increment by 1 hour.*/
  $('.period').each(function() {
    if (dh==cP) $(this).addClass('active'); // add active if current
    else $(this).removeClass('active'); // otherwise remove it
    cP++; // Add an hour each loop, assuming each period is 1hr
  });
}, 60000); // 60000 milliseconds = 1 minute update

Links to check out

Live Example - http://jsbin.com/okoso3
Live Example 2 (Revision) - http://jsbin.com/okoso3/2
About Date() - https://developer.mozilla.org/en/JavaScript/Reference/global_objects/date

Robert
+1, Nicely done, it's taken me over twenty minutes in jQuery to get anywhere near this. And I'm still stuck on the repetition part... =/
David Thomas
That's not exactly what I'm looking for. I have all of the periods already existing as `div`'s (see http://gist.github.com/598431). I just want it to add an `id` to the current period, not change the period.
Ethan Turkeltaub
I'm not 100% on what you're trying to achieve in doing that. Are you trying to style the current period, or what?
Robert
@Robert: Yes, indeed. I'm trying to highlight the current period so the students will see what period it is without thinking too hard. I need to add the `id` to do that.
Ethan Turkeltaub
Just modify my function, instead of setting the variable p depending on the time, style your element.
Robert
Could you explain how I could do this? Sorry, I don't know a bit of Javascript at all...
Ethan Turkeltaub
Edited the answer, used some jQuery because I think it'll be the easiest to understand
Robert
I'm still confused. I have the source on GitHub (the HTML/eRB is at /app/views/clock.erb, the JavaScript is at /public/application.js). http://github.com/eturk/fhsclock
Ethan Turkeltaub
Look at my latest live example. If you need you can click "Edit using JSBin" and it will show you my source. I made 7 `div`'s, which you can put your periods in. The script highlights a specific `div` in bold letters determined by the current hour.
Robert
I'm leaving the office for the day. Hopefully the latest revision helps you, if not scanning over Jey's real quick it looks like that should work as well, check that out if you can't figure out mine.
Robert
I got it to work, thanks a lot.
Ethan Turkeltaub
+1  A: 

Your HTML markup should resemble this:

<div class="period 1">
  <input type="hidden" name="time" value="7" class="start_time_hour" />
  <input type="hidden" name="time" value="32" class="start_time_min" />
  <input type="hidden" name="time" value="8" class="end_time_hour" />
  <input type="hidden" name="time" value="14" class="end_time_min" />
  Period 1: 7:32-8:14</div>
</div>

Your javascript will look like this:

var elements = $('.period');
function update_status() {
  elements.each(function() {
    var current = new Date();
    var sH = parseInt($(this).find('.start_time_hour').val());
    var sM = parseInt($(this).find('.start_time_min').val());
    var eH = parseInt($(this).find('.end_time_hour').val());
    var eM = parseInt($(this).find('.end_time_min').val());

    if (current.getHours() >= sH && current.getHours() <= eH && current.getMinutes() >= sM && current.getMinutes() <= eM) {
      $(this).setAttr('id', 'active');
    }
  });
}
setInterval(update_status, 1000);

There are definitely ways of doing this better, but this will do the job. I would have passed in the time in milliseconds since epoch but I assume you are basing the active status on time rather than date & time. If it's based on date and time, you can pass in the milliseconds since epoch instead of hours and minutes.

Jey Balachandran