/ Kevin's Calendar
//
//
// JavaScript Event Calendar
//
// Version: 1.0
// Date: November 15, 1998
// By Kevin Ilsen
// For information: http://calendar.ilsen.net
//
// * This is a modification of the calendar by John Banister in mid-January 2008.
// * It's available as www.John.Banister.name/Calendar3.txt (rename it to .js to use it)
// * I made it for my mother to use at http://mysite.verizon.net/RowlesburgWV/Rowesburgnewsandevents.htm
// * This script expects a server to provide it with events stored in a .csv file named
// * by the variable csv_file below. If you computer at home isn't a server,
// * or your server doesn't have such a file then it won't work there. The format of the
// * .csv file is that created by choosing File -> Export -> Events in Broderbund's
// * Calendar Creator. It uses the date as formatted by Calendar Creator in the first
// * "column," the event name in the fourth "column," and ignores everything else.
// * It wouldn't be to hard to modify my BCCcsv_to_events function to handle other types
// * of csv files.
// * I'm building the table in the DOM fashion following the example set at
// * http://developer.mozilla.org/en/docs/Traversing_an_HTML_table_with_JavaScript_and_DOM_Interfaces
// * and many places at www.w3schools.com
// * So it can be inserted in the manner suggested by James Edwards at
// * http://www.sitepoint.com/blogs/2007/07/11/insert-in-place-without-documentwrite/
// *
// * Note:
// * Instead of putting and
// *
// *
// * If you use this with any other script containing calls to DefineEvent
// * The tags have to appear in the web page AFTER
// * the one with the reference to Calendar3.js or else, the browser thinks DefineEvent
// * is a variable instead of a function, and it doesn't work.
// Configurable values are set to defaults here; can override them before calling Calendar( ) from the HTML page
var SpecialDay=1; // 1=Sunday, 2=Monday, . . . 7=Saturday
var FontSize=25;
var SmallFontSize=14;
var ColorBackground = "ffffcc";
var EventBackground = "b4b492";
var EventTextColor = "fdff6c";
var ColorSpecialDay = "red";
var ColorToday = "green";
var ColorEvent = "blue";
var csv_file = "Town_Events.csv" ;
// Initialize the range of the calendar to Jan - Dec of the current year. Calls to DefineEvent( ) will change this
// as needed; it is also possible to explicitly override the range before calling Calendar( ) from the HTML page.
var today = new Date();
var FirstMonth=GetFullYear(today) * 100 + 1;
var LastMonth=FirstMonth + 11;
var Town_Event_Date = 19950101 ;
var Town_Event_Text = "Not a big event" ;
// Events[] is a SPARSE array; Call DefineEvent( ) to populate it
var Events = new Array();
// Each event is defined by calling the DefineEvent( ) routine with the following parameters:
//
// DefineEvent(EventDate, EventDescription, EventLink, Image, Width, Height)
// EventDate is a numeric value in the format YYYYMMDD
// EvenDescription is a string that can include embedded HTML tags (e.g.,
, , etc.)
// EventLink is the URL of the target page if a hyperlink is desired from this event entry
// Image is the URL of the image if you want to display an image with this event
// Width is the width of the image in pixels
// Height is the height of the image in pixels
function DefineEvent(EventDate, EventDescription, EventLink, Image, Width, Height) {
var eventTableBody = null ;
if ( ! Events[EventDate]) {
var eventTable = document.createElement('table') ;
var eventTableBody = document.createElement('tbody') ;
eventTable.appendChild(eventTableBody) ;
eventTable.width = '100%' ;
eventTable.border = 3 ;
eventTable.cellSpacing = '3px' ;
eventTable.style.backgroundColor = ColorBackground ;
Events[EventDate] = eventTable ;
} else {
eventTableBody = Events[EventDate].tBodies[0] ;
}
var eventRow = document.createElement('tr') ;
var eventCell = document.createElement('td') ;
eventRow.appendChild(eventCell) ;
eventCell.style.backgroundColor = EventBackground ;
eventCell.style.color = EventTextColor ;
eventCell.align = 'center' ;
// Build the Paragraph object for the text, image, and link.
// If EventLink exists it needs to append the text & image and
// then get appended in turn.
var eventText = null;
if (EventDescription.length > 0) {
eventText = document.createTextNode(EventDescription) ;
}
var eventImage = null;
if (Image.length > 3) {
eventImage = document.createElement('img') ;
eventImage.src = Image ;
eventImage.width = Width ;
eventImage.height = Height ;
eventImage.align = "left" ;
}
if (EventLink.length > 2) {
var tmpLink = document.createElement('a') ;
tmpLink.href = EventLink ;
if (eventImage || eventText) {
if (eventImage) tmpLink.appendChild(eventImage) ;
if (eventText) tmpLink.appendChild(eventText) ;
} else {
tmpLink.appendChild(document.createTextNode('Link')) ;
}
eventCell.appendChild(tmpLink) ;
} else {
if (eventImage) {
eventCell.appendChild(eventImage) ;
}
if (eventText) {
eventCell.appendChild(eventText) ;
}
}
if (eventCell.firstChild) {
eventTableBody.appendChild(eventRow) ;
}
// Adjust the minimum and maximum month & year to include this date
tmp = Math.floor(EventDate / 100);
if (tmp < FirstMonth) FirstMonth = tmp;
if (tmp > LastMonth) LastMonth = tmp;
}
// Utility function to populate an array with values
function arr() {
for (var n=0;n lastday) {
thisCellText = document.createTextNode('\u00A0') ;
thisCell.appendChild(thisCellText) ;
}
// Otherwise, write date and the event,
// if any, in this cell of the table.
else {
ShowDate(yr,mo,dy,i,curmo,curdy,thisCell);
dy++;
}
thisRow.appendChild(thisCell) ;
}
CalendarTableBody.appendChild(thisRow) ;
var thisRow = document.createElement("tr") ;
}
var prevNext = document.createElement('p')
prevNext.style.fontSize = SmallFontSize ;
if (yearmonth > FirstMonth) {
var linkPrevious = document.createElement('a') ;
linkPrevious.href = "Javascript: JumpTo(" + PrevYearMonth(yearmonth) + ") ;" ;
var linkText = document.createTextNode(" View " + months[PrevMonth(mo)]) ;
var leftArrowSpan = document.createElement("span") ;
// leftArrowSpan.style.fontWeight = "bold" ;
leftArrowSpan.appendChild(document.createTextNode("\u2190")) ;
linkPrevious.appendChild(leftArrowSpan) ;
linkPrevious.appendChild(linkText) ;
linkPrevious.style.textDecoration="none" ;
prevNext.appendChild(linkPrevious) ;
var titleCell = CalendarTableBody.firstChild.firstChild ;
titleCell.insertBefore(linkPrevious.cloneNode(true), titleCell.firstChild);
}
if ((yearmonth > FirstMonth) && (yearmonth < LastMonth)) {
var thisText = document.createTextNode("\u00A0 | \u00A0") ;
prevNext.appendChild(thisText) ;
}
if (yearmonth < LastMonth) {
var linkNext = document.createElement('a') ;
linkNext.href = "Javascript: JumpTo(" + NextYearMonth(yearmonth) + ") ;" ;
var linkText = document.createTextNode("View " + months[NextMonth(mo)] + " ");
linkNext.appendChild(linkText) ;
var rightArrowSpan = document.createElement("span") ;
// rightArrowSpan.style.fontWeight = "bold" ;
rightArrowSpan.appendChild(document.createTextNode("\u2192")) ;
linkNext.appendChild(rightArrowSpan) ;
linkNext.style.textDecoration="none" ;
prevNext.appendChild(linkNext) ;
var titleCell = CalendarTableBody.firstChild.firstChild ;
titleCell.appendChild(linkNext.cloneNode(true));
}
CalendarTableBody.appendChild(thisRow) ;
var thisRow = document.createElement("tr") ;
var thisCell = document.createElement("td") ;
thisCell.align = "center" ;
thisCell.colSpan = 7 ;
thisCell.appendChild(prevNext) ;
thisRow.appendChild(thisCell) ;
CalendarTableBody.appendChild(thisRow) ;
var thisRow = document.createElement("tr") ;
var thisCell = document.createElement("td") ;
thisCell.align = "center" ;
thisCell.colSpan = 7 ;
thisCell.vAlign = "middle" ;
var selectMonth = document.createElement("form") ;
var formText = document.createTextNode("Jump to month:\u00A0\u00A0") ;
selectMonth.appendChild(formText) ;
selectMonth.style.fontSize = SmallFontSize ;
var monthDropdown = document.createElement("select") ;
BuildSelectionList(yearmonth, monthDropdown) ;
selectMonth.appendChild(monthDropdown) ;
thisCell.appendChild(selectMonth) ;
thisRow.appendChild(thisCell) ;
CalendarTableBody.appendChild(thisRow) ;
TheCalendar.appendChild(CalendarTableBody) ;
}
// Display a date in the appropriate color, with events (if there are any)
function ShowDate(yr, mo, dy, dayofweek, currentmonth, currentday, thisCell) {
var ind, HighlightEvent, tmp;
thisCell.vAlign = "top" ;
var MonthDayPara = document.createElement("p") ;
MonthDayPara.style.textAlign = "right" ;
MonthDayPara.style.fontSize = FontSize ;
MonthDayPara.style.fontWeight = 'bold' ;
MonthDayText = document.createTextNode(dy) ;
MonthDayPara.appendChild(MonthDayText) ;
HighlightEvent = true;
if (dayofweek == SpecialDay) {
MonthDayPara.style.color = ColorSpecialDay ;
HighlightEvent = false;
}
if ((mo == currentmonth) && (dy == currentday)) {
MonthDayPara.style.color = ColorToday ;
HighlightEvent = false;
}
ind = (((yr * 100) + mo) * 100) + dy;
if (Events[ind]) {
if (HighlightEvent) {
MonthDayPara.style.color = ColorEvent ;
}
Events[ind].style.fontSize = SmallFontSize ;
thisCell.appendChild(MonthDayPara) ;
thisCell.appendChild(Events[ind]) ;
} else {
thisCell.appendChild(MonthDayPara) ;
EventText = document.createTextNode('\u00A0') ;
var EventPara = document.createElement('p') ;
EventPara.style.fontSize = SmallFontSize ;
EventPara.appendChild(EventText) ;
EventPara.appendChild(document.createElement("br")) ;
EventPara.appendChild(EventText) ;
thisCell.appendChild(EventPara) ;
}
thisCell.style.border = "solid"
thisCell.style.borderColor = document.bgColor
}
// Remaining routines are utilities used above
function NumDaysIn(mo,yr) {
if (mo==4 || mo==6 || mo==9 || mo==11) return 30;
else if ((mo==2) && LeapYear(yr)) return 29;
else if (mo==2) return 28;
else return 31;
}
function LeapYear(yr) {
if (((yr % 4 == 0) && yr % 100 != 0) || yr % 400 == 0) return true;
else return false;
}
// fixes a Netscape 2 and 3 bug
function GetFullYear(d) { // d is a date object
var yr;
yr = d.getYear();
if (yr < 1000)
yr +=1900;
return yr;
}
function PrevMonth(mth) {
if (mth == 1) return 12;
else return (mth-1);
}
function NextMonth(mth) {
if (mth == 12) return 1;
else return (mth+1);
}
function PrevYearMonth(yrmth) {
if ((yrmth % 100) == 1) return ((yrmth-100)+11);
else return (yrmth-1);
}
function NextYearMonth(yrmth) {
if ((yrmth % 100) == 12) return ((yrmth-11)+100);
else return (yrmth+1);
}
function JumpSelect() {
var monthDropdown = document.getElementById('selectMonth') ;
var thisyearmonth = monthDropdown.options[monthDropdown.selectedIndex].value ;
JumpTo(thisyearmonth) ;
}
function JumpTo(thisyearmonth) {
var mo = thisyearmonth % 100 ;
var yr = (thisyearmonth - mo) / 100 ;
var OldCalendar = document.getElementById('TheCalendarTable') ;
var TheCalendar = document.createElement("table") ;
BuildCalendar(TheCalendar, mo, yr) ;
var scr = document.getElementById('CalendarHere') ;
scr.parentNode.replaceChild(TheCalendar, OldCalendar) ;
}
function BuildSelectionList(current, monthDropdown) {
var mo, yr, thisyearmonth;
var index = 0 ;
thisyearmonth = FirstMonth;
monthDropdown.id = "selectMonth" ;
monthDropdown.size = 1 ;
monthDropdown.style.fontSize = SmallFontSize ;
// Quotes around "JumpSelect() ;" make the next line stop working.
monthDropdown.onchange = JumpSelect ;
while (thisyearmonth <= LastMonth) {
mo = thisyearmonth % 100 ;
yr = (thisyearmonth - mo) / 100 ;
var thisOption = document.createElement("option") ;
thisOption.value = thisyearmonth ;
if (thisyearmonth == current) {
thisOption.selected = true ;
thisOption.defaultSelected = true ;
}
thisOption.text = months[mo] + " " + yr ;
monthDropdown.options.add(thisOption, index) ;
index++;
thisyearmonth = NextYearMonth(thisyearmonth);
}
}
// I found this function in Stoyan Stefanov's article at
// http://www.sitepoint.com/article/take-command-ajax
makeHttpRequest(csv_file, 'CalendarizeContents');
function makeHttpRequest(url, callback_function)
{
var http_request = false;
if (window.XMLHttpRequest) { // Mozilla, Safari,...
http_request = new XMLHttpRequest();
if (http_request.overrideMimeType) {
http_request.overrideMimeType('text/xml');
}
} else if (window.ActiveXObject) { // IE
try {
http_request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
http_request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}
if (!http_request) {
alert('Unfortunatelly you browser doesn\'t support this feature.');
return false;
}
http_request.onreadystatechange = function() {
if (http_request.readyState == 4) {
if (http_request.status == 200) {
eval(callback_function + '(http_request.responseText)');
} else {
alert('There was a problem with the request.(Code: ' + http_request.status + ')');
}
}
}
http_request.open('GET', url, true);
http_request.send(null);
}
function CalendarizeContents(text) {
BCCcsv_to_events(text);
ShowCalendar();
}
// A lot of the ideas in this function originated in the words (code) of
// Laurent Bugnion (of GalaSoft) in replies to a question at
// http://www.thescripts.com/forum/thread91725.html
function BCCcsv_to_events(csv_events) {
var lines = csv_events.split('\n');
for (i=0; i < lines.length; i++) {
var One_Town_Event = lines[i].split( ',' ) ;
// Change Date from Calendar Creator format to Kevin's Calendar format
var strDate = One_Town_Event[0].split('/') ;
if (strDate[0].length != 2) {
if (strDate[0].length = 1) {
strDate[0] = "0" + strDate[0] ;
} else {
strDate[0] = "01" ;
}
}
if (strDate[1].length != 2) {
if (strDate[1].length = 1) {
strDate[1] = "0" + strDate[1] ;
} else {
strDate[1] = "01" ;
}
}
if (strDate[2].length != 4) {
if (strDate[2].length = 2) {
strDate[2] = "20" + strDate[2] ;
} else {
strDate[2] = "1995" ;
}
}
var Date_Str = strDate[2] + strDate[0] + strDate[1] ;
Town_Event_Date = parseInt(Date_Str);
// Extract the event text from the Calendar Creator .csv & strip quotes
Town_Event_Text = One_Town_Event[3].substring( 1, One_Town_Event[3].length - 1);
// Call DefineEvent with the appropriate null values in the other four spots
DefineEvent(Town_Event_Date, Town_Event_Text, "", "", 0, 0);
}
}