/**
* JavaScript Calendar
*
* @author David Miles
* @created 09/18/2010
* @revised 09/23/2010
*/
/**
* Load event
*/
window.onload = function(){
// Add click events to the anchor tags
document.getElementById("next").onclick = updateCalendar;
document.getElementById("prev").onclick = updateCalendar;
// Load the calendar
loadCalendar();
};
/**
* Click event handler for updating the calendar
*
* @return boolean
*/
function updateCalendar(){
// This regular expression will take the URL we're using
// this anchor and parse the hash in the format M-YYYY
var regex = new RegExp("#([0-9]{1,2})-([0-9]{4})$");
var results = regex.exec(this.href);
// Load a new calendar using the results of the regular
// expressions.
loadCalendar(results[1], results[2]);
// Don't actually follow the link
return false;
}
/**
* Load a calendar
*/
function loadCalendar(month, year){
// Declarations
var calendar = new Calendar(month, year);
// Fix for going to the next/previous years
var nextMonth = calendar.getMonth() == 11 ? 0 : calendar.getMonth() + 1;
var prevMonth = calendar.getMonth() == 0 ? 11 : calendar.getMonth() - 1;
var nextYear = calendar.getMonth() == 11 ? calendar.getYear() + 1 : calendar.getYear();
var prevYear = calendar.getMonth() == 0 ? calendar.getYear() - 1 : calendar.getYear();
// Load into page
document.getElementById("title").innerHTML = calendar.getMonthName() + ", " + calendar.getYear();
document.getElementById("calendar").innerHTML = calendar;
document.getElementById("next").href = "#" + nextMonth + "-" + nextYear;
document.getElementById("prev").href = "#" + prevMonth + "-" + prevYear;
}
/**
* Calendar class
*
* Builds a table-based calendar when constructed with a month and year
*/
function Calendar(month, year){
// Private Fields {{{
var _month = 0;
var _year = 0;
var _currentDate = new Date();
// }}}
// Constructor {{{
// If the month and year were not passed in, we must set defaults.
// Otherwise, use the arguments passed in
_month = month === undefined ? _currentDate.getMonth() : parseInt(month);
_year = year === undefined ? _currentDate.getFullYear() : parseInt(year);
// To get the first day of the month, create a new Date object
// and set the year and month to our private field values. Then,
// set the day of the month to the first
var _firstDay = new Date();
_firstDay.setYear(_year);
_firstDay.setMonth(_month);
_firstDay.setDate(1);
// A month may start in the middle of the week, and we will need
// to compensate for this. We store a reference to the day of the
// week to figure this out.
var _emptyDays = _firstDay.getDay();
// To get the last day of the month, clone the first day and
// increment the month, then set the hours to a negative number
var _lastDay = _firstDay;
_lastDay.setMonth(_month + 1);
_lastDay.setHours(-1);
// This will be used as a comparison string to figure out which day
// is today. If we don't store the current day, month, and year, then
// we run the risk of Sept. 21 showing up as today for Oct. 21
var _today = _currentDate.getDate() + "-"
+ _currentDate.getMonth() + "-"
+ _currentDate.getFullYear();
// }}}
// Public Methods {{{
/**
* Get current month name
*
* @param int i Month index (0-11)
* @return string
*/
this.getMonthName = function(){
var months = new Array("January", "February", "March", "April", "May"
, "June", "July", "August", "September", "October"
, "November", "December");
return months[_month];
}
/**
* Get the current year
*
* @return int
*/
this.getYear = function(){
return _year;
}
/**
* Get the current month
*
* @return int
*/
this.getMonth = function(){
return _month;
}
/**
* Convert to string
*
* @return string
*/
this.toString = function(){
// Declarations
var output = "";
var isToday = "";
var daysOfMonth = _emptyDays + _lastDay.getDate();
var daysLeft = daysOfMonth % 7 != 0 ? 7 - (daysOfMonth % 7) : 0;
// Start a table
output += "<table><tr>";
// Create day-of-the-week headers
for(var j = 0; j < 7; j++){
output += '<th>' + getDay(j).substring(0, 3) + '</th>';
}
// Start a new row
output += "</tr><tr>";
// If the beginning of the week is not the first day of the
// week, compensate by creating an empty column header
if(_emptyDays > 0){
output += '<th colspan="' + _emptyDays + '"> </th>';
}
// Now, loop through the days of the month
for(var i = _emptyDays, day = 1; i < daysOfMonth; i++, day++){
// Is this the end of the week?
if(i % 7 == 0){
output += "</tr><tr>";
}
// Is this the current day?
isToday = (day + "-" + _month + "-" + _year) == _today ? "today" : "";
// Add to output buffer
output += '<td id="' + isToday + '">' + day + '</td>';
}
// Complete the table by adding the remaining cells to the end
if(daysLeft > 0){
output += '<th colspan="' + daysLeft + '"> </th>';
}
// End our table
output += "</tr></table>";
return output;
}
// }}}
// Private Methods (((
/**
* Get day's string
*
* @param int i Day index (0-6)
* @return string
*/
getDay = function(i){
var days = new Array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday"
, "Friday", "Saturday");
return days[i];
}
// }}}
}
// }}}