// // Enhanced JavaScript Event Calendar // // Author: Rick Pike // Website: http://calendar.pikesys.com // Email: calendar@pikesys.com //'Version 0.3 - (07-May-2004) // // based on an earlier script by Kevin Ilsen (http://calendar.ilsen.net or kevin@ilsen.net) // Configurable values are set to defaults here; you can override them before calling Calendar( ) from your HTML page var SpecialDay=0; // 1=Sunday, 2=Monday, . . . 7=Saturday var ColorBackground=""; //normally "ffffcc" var ColorSpecialDay = "#807559"; //normally "red" var ColorToday = "#A84808"; //normally #BFA660 var ColorEvent = ""; //normally "blue" var showAltDate = false; // add display of alternate date using results from user supplied "getAltMonth(dy, mo, yr, last)" and "getAltDate(dy, mo, yr)" functions var showHolidays = false; // add display of holidays using result from user supplied "holidays(dy, mo, yr)" function var showAltHoly = false; // add display of alternate holidays using result from user supplied "getAltHoly(dy, mo, yr)" function var showMsgBox = false; // span empty cells (before 1st day and after last) for messageBox use var showMini = false; // add minimonth display of prior and next months if first and/or last boxes are available var showNav = true; // enable month navigation (might disable for print version) var showImages = true; // enable event images (might disable for print version) var showLinks = true; // enable event hyperlinks (might disable for print version) var msgBoxColor = "#ffcc99"; var navColor = "A8C4E3"; //normally "#ffff99" var imageAlign = "left"; // default event image alignment var imageScale = 100; // percent scale factor for images var altAlign = true; // alternate left/right alignment of event images on same date for readability var DefaultFormat = "layer"; // for compatibility; set to "layer" to simplify formatting var ExportPage = ""; // name of html page for displaying event text for export var PrintPage = ""; // name of html page for printer-friendly format // all format codes must have "|" to separate before and after tags var DateFontSize=4; var AltDateFormat = "|"; var MonthFormat = "|"; var AltMonthFormat = "
|"; var HolidayFormat = "
|
"; var AltHolyFormat = "
|
"; var DefaultLayerFormat = "|"; var defaultMsgBox = "Note: The information here may not be current; please confirm dates and times.

"; // Initialize the range of the calendar to Jan - Dec of the current year. // Event definitions will change this as needed; or it can be explicitly // overridden before calling Calendar( ) from the HTML page. var today = new Date(); var FirstMonth=GetFullYear(today) * 100 + 1; var LastMonth=FirstMonth + 11; // Layers[] is an array of layer names and default formats. Call DefineLayer( ) to add the // layer name and corresponding format. New layer names in event definitions will // be added automatically (watch case and spelling). var Layers = new Array; var LayerString = "|"; var layerCount = 0; var layerChange = true; // MsgBoxes[] is a SPARSE array; Call AddMsgBox( ) to populate it var MsgBoxes = new Array; // Events[] is a SPARSE array; Call AddEvent( ) to populate it or DefineEvent( ) for // compatibility with existing calendar definition scripts. var Events = new Array; // Each event is defined by calling the AddEvent( ) routine with the following parameters: // // AddEvent(Date, Description, Layer, Format, Link, Image, Width, Height, Align, Alt) // Date is a numeric value in the format YYYYMMDD // Description is a string (may include embedded HTML tags such as
, , etc.) // Layer is an event category whose display on the calendar can be toggled on/off by the user // Format specifies the source of the format info for Description. Note that any embedded // formats in Description will still be applied; this argument is primarily to provide // a more convenient way to specify formats. // "layer" = use default format from layer definition (plus any embedded tags!) // "custom" = only use format tags embedded in Description string // "<...>|" = series of before and after tags separated by a "|" to wrap around // Description (plus any embedded tags!) // Link 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 // Align is the alignment of the image such as "left", or "right" // Alt is the alternate text of the image (for mouseover or non-graphic browser) // The function DefineEvent(Date, Description, Link, Image, Width, Height) is used // for compatibility with previous calendar definition scripts // Event constructor function Event(description, layer, format, link, image, width, height, align, alt) { this.description = description; if (link) this.link = link; if (image) { this.image = image; if (width) this.width = width; if (height) this.height = height; if (align) this.align = align; if (alt) this.alt = alt; //alert("Event: ("+this.width+","+this.height+")"); } this.layer = (layer ? layer : "default"); // must have some associated layer if (format) { if (CheckFormat(format)) this.format = format; } } // Compatibility function for existing calendar definition scripts function DefineEvent(Date, Description, Link, Image, Width, Height) { AddEvent(Date, Description, "", "", Link, Image, Width, Height, "", ""); } function AddEvent(Date, Description, Layer, Format, Link, Image, Width, Height, Align, Alt) { var i; if (!Events[Date]) Events[Date] = new Array; i = Events[Date].length; Events[Date][i] = new Event(Description, Layer, Format, Link, Image, Width, Height, Align, Alt); // Adjust the minimum and maximum month & year to include this date tmp = Math.floor(Date / 100); if (tmp < FirstMonth) FirstMonth = tmp; if (tmp > LastMonth) LastMonth = tmp; // if EventLayer not in Layers, add it // NOTE: watch case in DefineLayer and DefineEvent to avoid undesired "duplicates" //alert("AddEvent("+Date+","+Description+","+Width+","+Height+"...)"); if (Layer && !Layers[Layer]) DefineLayer(Layer); } // Layer constructor function Layer(format, show) { if (format) { if (format.indexOf("|")>0) { this.format = format; } else { alert("Invalid Calendar Format String: " + format); } } else { this.format = DefaultLayerFormat; } this.show = (show=="false" ? "false" : "true"); // watch boolean vs. string arg } function DefineLayer(LayerName, LayerFormat, LayerShow) { Layers[LayerName] = new Layer(LayerFormat, LayerShow); layerCount++; } // Utility function to populate an array with values function arr() { for (var n=0;n FirstMonth) prev = ''; if (yearmonth < LastMonth) next += ''; } parseFormat(MonthFormat); tmp = ""; tmp += ""; tmp += ""; document.write(tmp); document.write(""); for (var i=1;i<=7;i++){ document.write(""); } dy = 1; document.write(""); while (dy <= lastdate) { for (var i=1; i<=7; i++) { // If the day cell is before the first day of the month, print a miniMonth display of previous month in the first cell, // otherwise print a space in this cell of the table. if (dy == 1 && i <= firstday) { if (i == 1) { if (showMini) { document.write(""); // If the day cell is after the last day of the month, print a miniMonth display of following month in the last cell, // otherwise print a space in this cell of the table. } else if (dy > lastdate) { if (i == 7) { if (showMini) { document.write(""); // Otherwise, write date and the event, if any, in this cell of the table. } else { document.write(""); dy++; } } document.write(""); } if (showNav) { prev = next = " "; if (yearmonth > FirstMonth) prev = '<-'+months[PrevMonth(mo)]+''; if (yearmonth < LastMonth) next += ''+months[NextMonth(mo)]+'->'; tmp = ""; // BG MOD removed tmp += ""; // BG MOD remove document.write(tmp + ""); if (layerCount>1) { document.write(""); } } document.write("
" + prev + "" + pre + "Beit Rayim Calendar — " + months[mo] + " " + yr + post; if (showAltDate) { parseFormat(AltMonthFormat); altMonth = getAltMonth(1, mo, yr, lastdate); tmp += pre + (altMonth ? altMonth : "") + post; } tmp += "" + next + "
"+weekdays[i]+"
"); MiniMonth(PrevYearMonth(yearmonth)); } else { document.write(" "); } } else if (showMsgBox && i==2) { // span empty cells to allow messageBox msgSpan = firstday - 1; document.write(" "); DoMsgBox(yearmonth, msgSpan); } else if (!showMsgBox) { document.write(" "); } document.write(""); MiniMonth(NextYearMonth(yearmonth)); } else { document.write(" "); } } else if (showMsgBox && i==(lastday+1)) { // span empty cells to allow messageBox msgSpan = 6 - lastday; document.write(" "); DoMsgBox(yearmonth, msgSpan); } else if (!showMsgBox) { document.write(" "); } document.write(""); ShowDate(yr,mo,dy,i,curmo,curdy); document.write("
" + prev + "
"; // BG MOD changed colspan from 5 to 7 re nav removal if (ExportPage) tmp += 'Export Events Displayed  |  '; tmp += 'Jump to month:  '; document.write(tmp); BuildSelectionList(yearmonth, thispage); if (PrintPage) document.write('  |  Print-friendly'); tmp = "
" + next + "
"); ChooseLayers(yearmonth, thispage); document.write("
"); } // Display a date in the appropriate color, with events (if there are any) function ShowDate(yr, mo, dy, dayofweek, currentmonth, currentday) { var ind, DayHighlighted, tmp, event; tmp = ""; // close tag BG MOD change document.write(tmp); if (showAltDate) { altDate = getAltDate(dy, mo, yr); parseFormat(AltDateFormat); document.write(""); } document.write("
"; tmp += "" + dy + (dy<10 ? " " : "") + " " + pre + altDate + post + "
"); if (showAltHoly) { tmp = getAltHoly(dy,mo,yr); if (tmp) { parseFormat(AltHolyFormat); document.write(pre + tmp + post + "
"); // removed
between quotation marks } } if (showHolidays) { tmp = holidays(dy,mo,yr); if (tmp) { parseFormat(HolidayFormat); document.write(pre + tmp + post + "
"); // removed
between quotation marks } } // document.write("

" + event ); images=0; for (j in Events[ind]) { ev = Events[ind][j]; tmp = ""; if (Layers[ev.layer].show == "true") { //alert("(+)showing event for "+ind+" in layer "+ev.layer); // Build the HTML string for this event tmp += (j>0 ? "
" : ""); // removed
between quotation marks if (ev.image && showImages) { if (ev.align) { align = ev.align; } else if (altAlign && images>0) { align = (lastAlign=="left" ? "right" : "left"); } else { align = imageAlign; } tmp += '' + ev.alt : '') +					   
					   ''; lastAlign = align; images++; } format = ""; if (ev.format == "layer") { // use format from layer (and embedded tags) format = Layers[ev.layer].format; } else if (ev.format == "custom") { // use only embedded tags format = ""; } else if (ev.format) { // format string? if (CheckFormat(ev.format)) format = ev.format; } else if (DefaultFormat == "layer") { // use format from layer if no custom format format = Layers[ev.layer].format; } parseFormat(format); tmp += pre + "" + (ev.link && showLinks ? ""+ev.description+"" : ev.description) + post + ""; // removed
between quotation marks } else { } document.write(tmp); } } function exportCal( ) { var curdy, curmo, yr, mo, dy, firstday, yearmonth, lastdate; // Save current day and month for comparison curdy = today.getDate(); curmo = today.getMonth()+1; initCal(curmo); mo = gloMo; yr = gloYr; yearmonth = gloYearmonth; getLayersVisible(); // Create a date object for the first day of the desired month lastdate = NumDaysIn(mo,yr); tmp = ""); } function getLayersVisible() { // get layer visibility settings from cookie prefix = cookieName + "|"; cookie = unescape(document.cookie); pos = cookie.indexOf(prefix); if (pos>=0) { pos += prefix.length; sep = cookie.indexOf(";"); if (sep == -1) sep = cookie.length; var layerCookies = cookie.substring(pos, sep).split("|"); for (i=0; i 1) { yearmonth = parseInt(location.search.substring(1,location.search.length)); if ((""+yearmonth).length == 6) { mo = yearmonth % 100; yr = (yearmonth - mo) / 100; } } // Constrain to the range of months with events if (yearmonth < FirstMonth) { mo = FirstMonth % 100; yr = (FirstMonth - mo) / 100; yearmonth = FirstMonth; } if (yearmonth > LastMonth) { mo = LastMonth % 100; yr = (LastMonth - mo) / 100; yearmonth = LastMonth; } gloMo = mo; gloYr = yr; gloYearmonth = yearmonth; } function qw(string) { return """ + string + """; } // Create a mini display of the desired month function MiniMonth(yearmonth) { var bgn, firstday, lastdate, miniweek; var days = new arr("S","M","T","W","T","F","S"); mo = yearmonth % 100; yr = (yearmonth - mo) / 100; bgn = new Date(months[mo] + " 1," + yr); // Get the day-of-week of the first day, and the # days in the month firstday = bgn.getDay(); lastdate = NumDaysIn(mo,yr); document.write("

 " + months[mo] + "
"); miniweek = " "; for (d in days) { miniweek += " " + days[d] + " "; } document.write(miniweek,""); dy = 1; // Rest of the weeks . . . while (dy <= lastdate) { miniweek = "
"; // removed
between quotation marks for (var i=1;i<=7;i++) { // If the day is less than the day of the week of the first day of the month, append spaces if (dy == 1 && i <= firstday){ miniweek += "   "; // End minimonth if the day > last day of the month } else if (dy > lastdate) { break; // Otherwise, append date (w/ extra space for single digits) } else { miniweek += " " + ( dy<10 ? " " : "" ) +dy; dy++; } } document.write(miniweek); } document.write("
"); } // 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) { return ( (yr%4 == 0 && yr%100 != 0) || yr % 400 == 0 ? true : false ); } // fixes a Netscape 2 and 3 bug function GetFullYear(d) { // d is a date object var yr = d.getYear(); return ( yr < 1000 ? yr + 1900 : yr ); } function PrevMonth(mth) { return ( mth == 1 ? 12 : mth - 1 ); } function NextMonth(mth) { return ( mth == 12 ? 1 : mth + 1 ); } function PrevYearMonth(yrmth) { return ( yrmth%100 == 1 ? yrmth-100+11 : yrmth-1 ); } function NextYearMonth(yrmth) { return ( yrmth%100 == 12 ? yrmth-11+100 : yrmth+1 ); } function JumpTo(calendar, thispage) { var sel, yrmo; sel = calendar.selectedIndex; yrmo = calendar.form.jumpmonth[sel].value; document.location = thispage + "?" + yrmo; } function BuildSelectionList(current, thispage) { var mo, yr, yearmonth; yearmonth = FirstMonth; tmp = ""); } // Create a message box function DoMsgBox(yearmonth, msgSpan) { if (MsgBoxes[yearmonth]) { for (j in MsgBoxes[yearmonth]) { // find first unshown message for month that fits monthlyMsg =MsgBoxes[yearmonth][j]; if (!monthlyMsg.shown) { //document.write("monthlyMsg.minspan = " + monthlyMsg.minspan + "
"); if (!monthlyMsg.minspan || monthlyMsg.minspan <= msgSpan) { tmp = ""; tmp += "
"+ monthlyMsg.message + "
"; document.write(tmp); monthlyMsg.shown = true; return; } } } } if (MsgBoxes[0]) { // show default MsgBox messages if they exists for (j in MsgBoxes[0]) { // find first unshown message for month that fits monthlyMsg =MsgBoxes[0][j]; if (!monthlyMsg.shown) { //document.write("monthlyMsg.minspan = " + monthlyMsg.minspan + "
"); if (!monthlyMsg.minspan || monthlyMsg.minspan <= msgSpan) { tmp = ""; tmp += "
"+ monthlyMsg.message + "
"; document.write(tmp); monthlyMsg.shown = true; return; } } } } } // Utility routines function escramVal(j,k){var a,b,c,d,e;a='';a+='lto:';b=j+'@';e='';b+=k;d=b;return(a+b+c+d+e);} function parseFormat(format) { // pre and post are globals pre = post = ""; if (format) { var sep = format.indexOf("|"); if (sep > 0) { // split format into pre and post strings pre = format.substring(0, sep); post= format.substring(1+sep, format.length); } } } function CheckFormat(String) { var okay; okay =(String == "layer" || String == "custom" || String.indexOf("|")>0); if (!okay) alert("Invalid Calendar Format String: " + String); return okay; } // MsgBox constructor function MsgBox(message,minspan,maxspan) { //alert("MsgBox("+message+","+minspan+","+maxspan+")"); this.message = message; this.minspan = (minspan ? minspan : 1); if (maxspan) this.maxspan = maxspan; //this.shown = false; } function AddMsgBox(yearmonth,message,minspan,maxspan) { var i; if (!MsgBoxes[yearmonth]) MsgBoxes[yearmonth] = new Array; i = MsgBoxes[yearmonth].length; MsgBoxes[yearmonth][i] = new MsgBox(message,minspan,maxspan); } function ChooseLayers(yearmonth, thispage) { var i, checked; tmp = '
Show Events: '; for (i in Layers) { if (i != "default") { checked = (Layers[i].show == "true" ? " checked" : ""); parseFormat(Layers[i].format); tmp += pre + '' + i + " " + post; } } //if (layerChange) { tmp += ' '; //} document.write(tmp + "
"); } function ChangeLayer(layer) { layerChange=true; Layers[layer].show = document.layerform[layer].checked; } function ApplyLayerChange(thispage, yearmonth) { layerChange=false; cookie = cookieName; for (layer in Layers) { if (layer != "default") { cookie += "|" + layer + "=" + Layers[layer].show; } } // persist cookie? document.cookie = escape(cookie); //alert("set cookie="+cookie); document.location = thispage + (yearmonth ? "?"+yearmonth : ""); }