Calendar addin

This is not an archive script, strictly speaking. It's more of a navigation device for your archive pages. If you have monthly archives, and you post a fair bit, it can be tough to find your posts from, say, April 9th, in the middle of a page full of all your April posts. This script draws a little monthly calendar, with the date numbers linked to your posts for that day (see an example in my testing blog). It requires a W3C DOM compliant browser (IE 5+, Netscape 6+, Mozilla...). It only works with monthly archives, and only on the archive pages, not on the main page (JavaScript can't tell what posts you might have in other files, so a calendar on the main page or in a weekly archive would just be misleading).

There are four pieces to the script, which need to go in four different spots in your main template. The bulk of the script goes in between the <head> and </head> tags. The onload="doOnloadTasks()" command goes inside your <body> tag (before the >). The <span id="CalendarHere"></span> goes where you want the calendar drawn. Finally, the section from <BlogDateHeader> to </BlogDateHeader> replaces your current BlogDateHeader, just below the <Blogger> tag (if you've done a lot of customizing of the date header, just insert the script section into your existing tags).

There is one change in the script that you absolutely must make, and several more you can make. At the top of the main script look for the line dateType = "1"; - read the instructions just above that, and be sure you change the "1" to the number for your style of date header. Below that are some styles that you can change to make the calendar fit into your page, month names and weekday abbreviations you can change if you like (and one set of month names that you have to change, if you use a language other than English and have the month name in your date header). The final change you might need to make is, if you already had something in your <body onload=, put it in the function doOnloadTasks() after the if (inArchives) drawCalendar(); line and before the }.

Once you've made those changes, save changes to your template, publish, and check your current archive page (when you publish, Blogger only republishes your current archive, not the older ones - we'll get them once everything's right). You'll probably have to do some adjusting of the style variables to get things to look right, but once you have published a version that you like in your current archive page, click the Archive button on the top toolbar in Blogger, and click republish all to put the calendar in all your archive pages.

There are two ways to copy the code for these scripts: either highlight the code on this page and copy, or for IE 5.x users, just click the "IE 5.x: Get the code" button to open the script code in two Notepad windows (one for the main section of code that goes in your <head> to </head>, and one for the other three pieces.

This section goes between <head> and </head>

<script type="text/javascript" language="JavaScript">

/* you absolutely, positively must change the value for dateType below to match your
   "Date Header Format" as set in your blog's Settings
   if your date format is:
   "Sunday, June 24, 2001" use 1
   "6/24/2001" use 2
   "6.24.2001" use 3
   "20010624" use 4
   "2001/06/24" use 5
   "2001-06-24" use 6
   "24.6.01" use 7
   "June 24, 2001" use 8
   "june 24, 2001" use 9
   something else, change to one of those and use the right number! */

dateType = "1";

tableFontStyle = "10px Verdana";
tableBackgroundStyle = "#eee";
tableBackgroundLinkStyle = "#ffff99";
// tableBorderStyle is the CSS style applied to the outside of the table, and around each cell
tableBorderStyle = "1px solid black";
// tableBorder is the ugly old HTML border attribute
tableBorder = "0";

/* change the lowMonthNames if you use a non-English language and you use one of the date styles
   with the month name in the date, but be sure they are in lower case (these are used for
   matching, not displaying */

lowMonthNames = new Array("january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december");

// you can change the displayMonthNames and displayWeekdayNames to anything that suits you

displayMonthNames = new Array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December");
displayWeekdayNames = new Array("Su", "Mo", "Tu", "We", "Th", "Fr", "Sa");

/* if you already do something with the body onload event (or want to later), add a call to
   it in this function or put the "if (inArchives) drawCalendar();" call in your existing
   onload function */
function doOnloadTasks(){
if (inArchives) drawCalendar();
}

// time to stop changing things, unless you are sure you know what you're doing!
links = new Array();
inArchives = false;
if (location.href.indexOf("<$BlogArchiveFileName$>") > -1) inArchives = true;

function datesplitter(date, datetype){
 switch(datetype){
  case "1" :
   date = date.substring(date.indexOf(",")+2);
   year = date.substring(date.length-4);
   day = date.substring(date.indexOf(" ")+1,date.indexOf(","));
   wordMonth = date.substring(0,date.indexOf(" "));
   wordMonth = wordMonth.toLowerCase();
   for (i = 0; i < 12; i++){
    if (lowMonthNames[i] == wordMonth){
     month = i;
     i = 12;
    }
   }
   break;
  case "2" :
   year = date.substring(date.length-4);
   month = date.substring(0,date.indexOf("/"));
   day = date.substring(date.indexOf("/")+1,date.lastIndexOf("/"));
   break;
  case "3" :
   year = date.substring(date.length-4);
   month = date.substring(0,date.indexOf("."));
   day = date.substring(date.indexOf(".")+1,date.lastIndexOf("."));
   break;
  case "4" :
   year = date.substring(0,4);
   month = date.substring(4,6);
   if (month.charAt(0) == "0") month = month.substring(1);
   day = date.substring(6);
   if (day.charAt(0) == "0") day = day.substring(1);
   break;
  case "5" :
   year = date.substring(0,4);
   month = date.substring(date.indexOf("/")+1,date.lastIndexOf("/"));
   if (month.charAt(0) == "0") month = month.substring(1);
   day = date.substring(date.lastIndexOf("/")+1);
   if (day.charAt(0) == "0") day = day.substring(1);
   break;
  case "6" :
   year = date.substring(0,4);
   month = date.substring(date.indexOf("-")+1,date.lastIndexOf("-"));
   if (month.charAt(0) == "0") month = month.substring(1);
   day = date.substring(date.lastIndexOf("-")+1);
   if (day.charAt(0) == "0") day = day.substring(1);
   break;
  case "7" :
   year = date.substring(date.length-2);
   if (year.charAt(0) == "0") year = year.charAt(1);
   year = parseInt(year);
   if (year < 50) year = 2000 + year; else year = 1900 + year;
   month = date.substring(date.indexOf(".")+1,date.lastIndexOf("."));
   day = date.substring(0,date.indexOf("."));
   break;
  case "8" :
   year = date.substring(date.length-4);
   day = date.substring(date.indexOf(" ")+1,date.indexOf(","));
   wordMonth = date.substring(0,date.indexOf(" "));
   wordMonth = wordMonth.toLowerCase();
   for (i = 0; i < 12; i++){
    if (lowMonthNames[i] == wordMonth){
     month = i;
     i = 12;
    }
   }
   break;
  case "9" :
   year = date.substring(date.length-4);
   day = date.substring(date.indexOf(" ")+1,date.indexOf(","));
   wordMonth = date.substring(0,date.indexOf(" "));
   for (i = 0; i < 12; i++){
    if (lowMonthNames[i] == wordMonth){
     month = i;
     i = 12;
    }
   }
   break;
  default :
   year = 1980;
   month = 1;
   day = 1;
 }
oDate = new Date(year, month, day);
return oDate;
}

function countDays(date){
 // given a date object, return number of days in that month
 monthcount = new Array ("31", "28", "31", "30", "31", "30", "31", "31", "30", "31", "30", "31");
 year = date.getFullYear();
 if (year % 4 == 0){
  if (year % 100 == 0){
   if (year % 400 == 0){
    monthcount[1]++;
    }
   }
  else {
   monthcount[1]++;
  }
 }
 return monthcount[date.getMonth()];
}

function drawCalendar(){
// only executes in a DOM compliant browser
if (document.getElementById){
if (document.createElement){
// IE is just barely compliant, if you use a deprecated style of attribute setting
navigator.appVersion.indexOf("MSIE") > 0 ? isIE = true : isIE = false;
 calStart = realDate;
 calStart.setDate(1);
 dayCount = countDays(calStart);
 leadblanks = calStart.getDay();
 oTable = document.createElement("TABLE");
 oTBody = document.createElement("TBODY");
 oRow = document.createElement("TR");
 oCell = document.createElement("TD");
 if (isIE)
  oCell.colSpan="7";
 else
  oCell.setAttribute("colspan", "7");
 oDateLabel = document.createTextNode(displayMonthNames[calStart.getMonth()] + " " + calStart.getFullYear());
 oCell.appendChild(oDateLabel);
 oRow.appendChild(oCell);
 oTBody.appendChild(oRow);
 oRow = document.createElement("TR");
 for (i=0;i<7;i++){
  oCell = document.createElement("TD");
  oCell.style.border = tableBorderStyle; 
  oDay = document.createTextNode(displayWeekdayNames[i]);
  oCell.appendChild(oDay);
  oRow.appendChild(oCell);
 }
 oTBody.appendChild(oRow);
 dayindex = 1;
 while (dayindex <= dayCount){
  oRow = document.createElement("TR");
  for (i=0;i<leadblanks;i++){
   oCell = document.createElement("TD");
   oCell.style.border = tableBorderStyle; 
   if (isIE)
    oSpace = document.createTextNode(" ");
   else
    {
     oSpace = document.createTextNode("*");
     oCell.style.color = tableBackgroundStyle;
    }
   oCell.appendChild(oSpace);
   oRow.appendChild(oCell);
   }
  for (b=leadblanks;b<7;b++){
   oCell = document.createElement("TD");
   oCell.style.border = tableBorderStyle;
   if (links[dayindex] != null){
    oLink = document.createElement("A");
    if (isIE)
     oLink.href=links[dayindex];
    else
     oLink.setAttribute("href", links[dayindex]);
    oLinkText = document.createTextNode(dayindex);
    oLink.appendChild(oLinkText);
    oCell.appendChild(oLink);
    oCell.style.background = tableBackgroundLinkStyle;
    }
   else
    if (dayindex <= dayCount){
     oDayText = document.createTextNode(dayindex);
     oCell.appendChild(oDayText);
     }
    else {
     if (isIE)
      oSpace = document.createTextNode(" ");
     else
      {
       oSpace = document.createTextNode("*");
       oCell.style.color = tableBackgroundStyle;
      }
     oCell.appendChild(oSpace);
     }
   oRow.appendChild(oCell);
   oTBody.appendChild(oRow);
   dayindex++;
   }
   leadblanks = 0;
  }
oTBody.style.font = tableFontStyle;
oTBody.style.textAlign = "center"; 
oTable.appendChild(oTBody);
if (isIE)
 oTable.style.background = tableBackgroundStyle;
else
 oTable.setAttribute("bgColor", tableBackgroundStyle);
oTable.border = tableBorder;
oTable.style.border = tableBorderStyle;
calendarSpot = document.getElementById("CalendarHere");
calendarSpot.appendChild(oTable);
}
}
}
</script>

This goes in your <body> tag

<body onload="doOnloadTasks()">

This goes where you want the calendar to appear

<span id="CalendarHere"><!-- tells the script where to put the calendar --></span>

This replaces your <BlogDateHeader> to </BlogDateHeader> section

<BlogDateHeader>
  <script type="text/javascript">
  var postDate="<$BlogDateHeaderDate$>";
  realDate = datesplitter(postDate,dateType);
  anchorDate = realDate.valueOf();
  links[realDate.getDate()] = "#d" + anchorDate;
  document.write("<a name='d" + anchorDate + "'</a>");
  </script>
  <$BlogDateHeaderDate$>
</BlogDateHeader>



Valid HTML 4.01! Valid CSS!