Two simple ColdFusion calendar outputs

  • October 26, 2009
  • James Skemp
  • article

Here's two rough drafts of calendars created via ColdFusion (7, but I believe 6.1 would have the same functionality).

Tables-based

<cfparam name="URL.CalendarMonth" default="#Month(now())#" type="integer" />
<cfparam name="URL.CalendarYear" default="#Year(now())#" type="integer" />

<cfif URL.CalendarMonth LT 1 OR URL.CalendarMonth GT 12>
    <cfset URL.CalendarMonth = Month(now()) />
</cfif>

<cfset VARIABLES.Calendar.StartDate = CreateDate(URL.CalendarYear, URL.CalendarMonth, 1) />

<table style="width:375px;" summary="Calendar of events for <cfoutput>#DateFormat(VARIABLES.Calendar.StartDate, 'mmmm yyyy')#</cfoutput>.">
    <thead>
        <tr>
            <th colspan="7"><cfoutput>#DateFormat(VARIABLES.Calendar.StartDate, "mmmm yyyy")#</cfoutput></th>
        </tr>
        <tr>
            <th>S</th>
            <th>M</th>
            <th>T</th>
            <th>W</th>
            <th>Th</th>
            <th>F</th>
            <th>S</th>
        </tr>
    </thead>
    <tbody>
        <cfloop from="1" to="#DaysInMonth(VARIABLES.Calendar.StartDate)#" index="iDay">
            <cfset VARIABLES.Calendar.CurrentDate = CreateDate(URL.CalendarYear, URL.CalendarMonth, iDay) />
            <cfif DayOfWeek(VARIABLES.Calendar.CurrentDate) EQ 1 OR iDay EQ 1><!--- This is Sunday, or the first day. --->
                <tr>
            </cfif>
            <cfif iDay EQ 1><!--- If it's the first day, determine how many empty cells we need. --->
                <cfoutput>#RepeatString("<td></td>", DayOfWeek(VARIABLES.Calendar.StartDate) - 1)#</cfoutput>
            </cfif>
                <cfoutput><td><span title="#DateFormat(VARIABLES.Calendar.CurrentDate, 'mmmm d, yyyy')#">#iDay#</span></td></cfoutput>
            <cfif iDay EQ DaysInMonth(VARIABLES.Calendar.StartDate)>
                <cfoutput>#RepeatString("<td></td>", 7 - DayOfWeek(VARIABLES.Calendar.CurrentDate))#</cfoutput>
            </cfif>
            <cfif DayOfWeek(VARIABLES.Calendar.CurrentDate) EQ 7 OR iDay EQ DaysInMonth(VARIABLES.Calendar.StartDate)><!--- This is Saturday, or the last day. --->
                </tr>
            </cfif>
        </cfloop>
    </tbody>
</table>

Ordered list and CSS

The following is a rough version of an ordered list and CSS-based calendar.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title></title>
    <style type="text/css">
    .olCalendar {
        width:375px;
    }
    .olCalendar ol li {
        display:block;
        float:left;
        list-style-position:inside;
        margin:0;
        width:45px;
    }
    .olCalendar li.noDate {
        list-style-image:none;
    }
    </style>
</head>
<body>
<cfparam name="URL.CalendarMonth" default="#Month(now())#" type="integer" />
<cfparam name="URL.CalendarYear" default="#Year(now())#" type="integer" />

<cfif URL.CalendarMonth LT 1 OR URL.CalendarMonth GT 12>
    <cfset URL.CalendarMonth = Month(now()) />
</cfif>

<cfset VARIABLES.Calendar.StartDate = CreateDate(URL.CalendarYear, URL.CalendarMonth, 1) />
<div class="olCalendar">
    <ol start="<cfoutput>#2 - DayOfWeek(VARIABLES.Calendar.StartDate)#</cfoutput>">
        <cfloop from="1" to="#DaysInMonth(VARIABLES.Calendar.StartDate)#" index="iDay">
            <cfset VARIABLES.Calendar.CurrentDate = CreateDate(URL.CalendarYear, URL.CalendarMonth, iDay) />
            <cfif iDay EQ 1><!--- If it's the first day, determine how many empty cells we need. --->
                <cfoutput>#RepeatString('<li class="noDate"> </li>', DayOfWeek(VARIABLES.Calendar.StartDate) - 1)#</cfoutput>
            </cfif>
                <cfoutput><li class="#LCase(DayOfWeekAsString(DayOfWeek(VARIABLES.Calendar.CurrentDate)))#"><span title="#DateFormat(VARIABLES.Calendar.CurrentDate, 'mmmm d, yyyy')#">#iDay#</span></li></cfoutput>
            <cfif iDay EQ DaysInMonth(VARIABLES.Calendar.StartDate)>
                <cfoutput>#RepeatString('<li class="noDate"> </li>', 7 - DayOfWeek(VARIABLES.Calendar.CurrentDate))#</cfoutput>
            </cfif>
        </cfloop>
    </ol>
</div>

</body>
</html>

But, let's be honest, this version sucks. I think tables are a necessary evil in this regard.

EDIT 12/21/2009: Corrected StartDate/CurrentDate mistake with repeating td elements.