/ 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); } }