Reputation: 397
I'm working on a little website that houses some resources for one of the departments at my university. Everything is coming along pretty well, so I'm trying to add a little bit of functionality to make things more intuitive.
If you want to see the full HTML structure and everything else, here's the page in question: {link removed to protect personal content}
Basically, it's a table with a row dedicated to each of the camps that we're responsible for this summer. This is all fine and dandy. What I want to do, now, is highlight the rows of any camps currently in session (by adding the class "active" to the row). Given my fairly limited experience with JavaScript, this is what I came up with:
<script type="text/javascript" >
$(document).ready(function() {
var today = new Date();
var Traffic_Court_Start = new Date("May 31 2012 12:01 AM");
var Traffic_Court_Stop = new Date("June 1 2012 11:59 PM");
var Summer_Enrichment_Start = new Date("June 10 2012 12:01 AM");
var Summer_Enrichment_Stop = new Date("June 16 2012 11:59 PM");
var Wbb_Ind_Start = new Date("June 11 2012 12:01 AM");
var Wbb_ind_Stop = new Date("June 14 2012 11:59 PM");
var Soccer_Referee_Start = new Date("June 15 2012 12:01 AM");
var Soccer_Referee_Stop = new Date("June 16 2012 11:59 PM");
var Broadcast_Start = new Date("June 17 2012 12:01 AM");
var Broadcast_Stop = new Date("June 21 2012 11:59 PM");
var Tennis_1_Start = new Date("June 17 2012 12:01 AM");
var Tennis_1_Stop = new Date("June 21 2012 11:59 PM");
var Tennis_2_Start = new Date("June 24 2012 12:01 AM");
var Tennis_2_Stop = new Date("June 28 2012 11:59 PM");
var Volleyball_Start = new Date("July 8 2012 12:01 AM");
var Volleyball_Stop = new Date("July 11 2012 11:59 PM");
var Soccer_1_Start = new Date("July 8 2012 12:01 AM");
var Soccer_1_Stop = new Date("July 12 2012 11:59 PM");
var IACAC_Start = new Date("July 9 2012 12:01 AM");
var IACAC_Stop = new Date("July 11 2012 11:59 PM");
var Summer_Forensics_Start = new Date("July 15 2012 12:01 AM");
var Summer_Forensics_Stop = new Date("July 28 2012 11:59 PM");
var Soccer_2_Start = new Date("July 22 2012 12:01 AM");
var Soccer_2_Stop = new Date("July 26 2012 11:59 PM");
var Cross_Country_Start = new Date("July 25 2012 12:01 AM");
var Cross_Country_Stop = new Date("July 28 2012 11:59 PM");
if((today <= Traffic_Court_Stop && today >= Traffic_Court_Start))
{
document.getElementById('traffic_court').classList.add('active');
};
if((today <= Summer_Enrichment_Stop && today >= Summer_Enrichment_Start))
{
document.getElementById('summer_enrichment').classList.add('active');
};
if((today <= Wbb_Ind_Stop && today >= Wbb_Ind_Start))
{
document.getElementById('wbb_ind').classList.add('active');
};
if((today <= Soccer_Referee_Stop && today >= Soccer_Referee_Start))
{
document.getElementById('soccer_referee').classList.add('active');
};
if((today <= Broadcast_Stop && today >= Broadcast_Start))
{
document.getElementById('broadcast').classList.add('active');
};
if((today <= Tennis_1_Stop && today >= Tennis_1_Start))
{
document.getElementById('tennis_1').classList.add('active');
};
if((today <= Tennis_2_Stop && today >= Tennis_2_Start))
{
document.getElementById('tennis_2').classList.add('active');
};
if((today <= Volleyball_Stop && today >= Volleyball_Start))
{
document.getElementById('volleyball').classList.add('active');
};
if((today <= Soccer_1_Stop && today >= Soccer_1_Start))
{
document.getElementById('soccer_1').classList.add('active');
};
if((today <= IACAC_Stop && today >= IACAC_Start))
{
document.getElementById('IACAC').classList.add('active');
};
if((today <= Summer_Forensics_Stop && today >= Summer_Forensics_Start))
{
document.getElementById('summer_forensics').classList.add('active');
};
if((today <= Soccer_2_Stop && today >= Soccer_2_Start))
{
document.getElementById('soccer_2').classList.add('active');
};
if((today <= Cross_Country_Stop && today >= Cross_Country_Start))
{
document.getElementById('cross_country').classList.add('active');
};
});
</script>
As you can see, I start by getting today's date, then I specify the start and end dates for each of the camps. Then, I use a bunch of if-statements to determine if 'today' is in between the start and end dates for each camp. If that is true, it adds the class "active" to the row corresponding to that camp.
It seems to work correctly for the first two camps...that is, if I change the value of 'today' to May 31 it highlights the first row. Or if I change it to June 15 it highlights the second row. The problem is that if 'today' is June 15, it should highlight BOTH the summer_enrichment and soccer_referee rows. It only highlights the summer_enrichment row.
I've double-checked the element IDs that I reference, the spelling of my variables, etc. and everything seems to look correct (unless I missed something obvious). Is there any reason why I can't use the script as I've presented it? I don't think this is the case, but is there a problem with using so many if-statements in a row like that? My only thought is that perhaps it thinks they are a bunch of else-cases but I thought I'd escape that with the semi-colon after each if-statement.
Any thoughts? Perhaps a better way to do this? I looked around for some answers but couldn't seem to find something similar anywhere else (though I'm sure this has been done before and with better implementation).
THANKS FOR YOUR HELP!!!
EDIT: After getting everything to work with the help of some of these responses, I figured I'd share the final code for future users who might stumble upon this question.
<script type="text/javascript">
$(document).ready(function() {
var today = new Date();
var SCHEDULE = {
'tc': ['May 31 2012', 'June 1 2012'],
'se': ['June 10 2012', 'June 16 2012'],
'wbb': ['June 11 2012', 'June 14 2012'],
'sr': ['June 15 2012', 'June 16 2012'],
'broadcast': ['June 17 2012', 'June 21 2012'],
'ten1': ['June 17 2012', 'June 21 2012'],
'ten2': ['June 24 2012', 'June 28 2012'],
'volleyball': ['July 8 2012', 'July 11 2012'],
'soc1': ['July 8 2012', 'July 12 2012'],
'iacac': ['July 9 2012', 'July 11 2012'],
'sf': ['July 15 2012', 'July 28 2012'],
'soc2': ['July 22 2012', 'July 26 2012'],
'cc': ['July 25 2012', 'July 28 2012']
};
for (var camp in SCHEDULE) {
console.log('checking ' + camp + ', dates have to be within the ' + SCHEDULE[camp] + ' range');
//console.log(Date.parse(SCHEDULE[camp][0]));
if (today >= Date.parse(SCHEDULE[camp][0]) && today <= Date.parse(SCHEDULE[camp][1])) {
console.log(camp + ' is currently in session!');
document.getElementById(camp).classList.add('active');
};
};
});
</script>
THANKS A LOT EVERYONE!!!
Upvotes: 2
Views: 2939
Reputation: 538
Here's an attempt. Since you're not using a database, try storing your dates as data attributes. Convert them to timestamps so you can compare: http://jsfiddle.net/uJEJ7/26/
I'm sure I'm overlooking something, but maybe it'll spark an idea.
I noticed your page is written in PHP, it might be easier to go that route. Store your Camp data in an associative array, loop through it to generat the table rows, and output markup based on if your dates match.
Good luck!
Upvotes: 1
Reputation: 147413
Comment:
In your code:
> var Traffic_Court_Start = new Date("May 31 2012 12:01 AM");
is dependent on regional settings understanding that date string format. Parsing of dates is implementation dependent and there is no reason to believe a US-specific format will work in all browers for all regions. The only format that is specified is ISO8601 in ES5 and not all browsers support that either. No format at all is specified in the earlier ECMAScript ed 3.
Also, the above creates a date object in the local timezone of the client, so two clients with different timezone settings (say one with daylight saving and one without) will resolve it to two different times.
If you must work with dates on the client, far better to do everything in UTC and convert to local date objects only where necessary. Also, confirm with the user that your code has got it right (e.g. display what you think the current date and time is based on the sysetm settings, which might be wrong or not synchronised with its current location).
Creating a local date object from UTC values is simple using Date.UTC():
var date = new Date(Date.UTC (year, month[, date[, hours[, minutes[, seconds[, ms]]]]]);
which can be turned into a simple function that accepts whatever format you like.
Upvotes: 1
Reputation: 24988
I'd suggest the logic be done on the server-side so that unhighlighted content does not "flash" plus a marginal improvement in performance. An arguably more important improvement will be consistent rendering regardless of the client's time settings.
While I strongly advocate the above, the JS solution could be made into something more maintainable as well. Structure your code to contain a reusable function to check date against range and apply a class and normalize the way date references are stored:
var TODAY = new Date();
//Individual dates could be organized as objects,
//but using arrays below seems to be more readable and tidy
var SCHEDULE = {
'some-class': ['May 5 2011', 'June 5 2011'],
'some-class-a': ['May 5 2012', 'June 5 2012'],
'some-class-b': ['May 10 2012', 'June 10 2012'],
'some-class-c': ['May 15 2012', 'June 15 2012'],
'some-class-d': ['May 20 2012', 'June 20 2012'],
'some-class-e': ['May 25 2012', 'June 25 2012']
};
for (var camp_ in SCHEDULE) {
if (TODAY >= Date.parse(SCHEDULE[camp_][0]) && TODAY <= Date.parse(SCHEDULE[camp_][1])) {
document.getElementById(camp_).classList.add('active');
}
}
Working fiddle here: http://jsfiddle.net/ovfiddle/bMBcq/
Upvotes: 2
Reputation: 46497
Check out date.js, specifically...
http://code.google.com/p/datejs/wiki/APIDocumentation#compare
Compares the first date to the second date and returns an number indication of their relative values. -1 = this is < date. 0 = values are equal. 1 = this is > date.
The isAfter()
and the isBefore()
methods might be useful for your problem :)
Download the library here:
http://code.google.com/p/datejs/downloads/detail?name=date.js&can=2&q=
Also, its worth mentioning to checkout moment.js. I think the two libraries complement each other.
Upvotes: 0
Reputation: 11764
I am not sure if you can use the greater/less-than operator on dates, but comparing their time stamps will definitely work as you will be working with numbers (milliseconds)
You can get timestamps like this:
var today = new Date().getTime();
Upvotes: 0