coldFusion calendar code

calendar
distinctPixel coldFusion calendar
v1.0

so here's the inital release of the source code for the ColdFusion calendar i wrote last night. It requires coldFusion server 5.0 or later and is free for you to use and abuse. my only request is that you let me know if it helps!

distinctPixel coldFusion calendar module

v1.0

you can download the source file here.

so here's how it works:

The first thing we need to do is determine the month and year that we want to display. the default is this month, but it can also grab the date from the queryString ?cal=mm/dd/yyyy.

from the month and year of the date provided, we create a new date variable, (thisDate) we’re also, forcing the day value to be “01”. (since it’s a monthly calendar, and we always start the month on the first... duh.)

<cfif isDefined("URL.cal")>
<cfset newDate=#URL.cal#>

<cfelse> <cfset newDate=now()> </cfif> <cfset name=“thisMonth” default=#month(newDate)#> <cfset name=“thisYear” default=#year(newDate)#>

<cfset thisDate=#createDate(thisYear, thisMonth, 01)#>

next, we set some variables based on the thisDate value for the next and previous buttons on the calendar.

<cfset prevDate=#dateAdd("m", -1, thisDate)#>

<cfset nextDate=#dateAdd(“m”, 1, thisDate)#>

now we set some initial variables for looping through the days/weeks.

<cfset weekStart=1>
<cfset weekEnd=weekStart+6>

from here, I ran a query against a table in my database to grab all the entires that would fall in this month that i would want to highlight. I used the SQL CONVERT command to return the date values as a mm/dd/yyyy string. This isn’t really necessary, but I found it easier to work with and debug when the values were “human readable” vs. the normal SQL ODBCdateTime format. I also used the DISTINCT SQL command, so I would only get one value for each day. The WHERE clause is just there to help limit the data returned to with in the last month or so, so the queries don’t take forever on larger datasets. this is pretty lose, can certainly be cleaned up in the future.

<cfquery name="getDates" datasource="yourDSN">
SELECT DISTINCT CONVERT(char(10), theTimeStamp, 101) AS dateList
FROM dp_blog 
WHERE theTimeStamp BETWEEN #createODBCdate(prevDate)# 
AND #createODBCdate(nextDate)#
</cfquery>

now here comes the fun part. My first use of a ColdFusion User Defined Function (UDF). This <CFSCRIPT> tag consists of a function writeDate() that actually writes out the “<td>day(with link)</td>” HTML. I put it into a function like this, so I could test each day value passed and determine if it’s today, the future, or the past (and apply the according styles for this ), and finally, if there are any DB entries for this day make the day linkable. The function works by passing the year, the month, and the day of the date, as well as a list of dates that have entries.

<cfscript>
//writeDate function(year, month, day, list of active days)
function writeDate(y, m, d, dateList) {
str="<td ";
theDate=createDate(y, m, d);

//using a “switch” to loop through the conditions of //the dateCompare() future, past and now. //dateCompare() returns values of -1, 0, or 1 //this is where it’s pointless to return the date //as mm/dd/yyyy, we just end up converting it anyway ;) switch(dateCompare(createODBCdate(theDate), createODBCdate(now()))) { case 1: //this is the future, give it the future class str=str & ” class=""dateDisabled"" ”; break; case 0: //this is today, mark use it’s class. str=str & ” class=""dateToday"" ”; break; default: //this is the past str=str & ” class=""dateNormal"" ”; }

str=str & ” >”; //now look in the list… if(listContains(dateList, dateFormat(theDate, “mm/dd/yyyy”)) GT 0) { //this day has an action attached. bold, and link to information //replace with your link theLink=“#CGI.SCRIPT_NAME#?cal=” & #dateFormat(theDate, “mm/dd/yyyy”)#; str= str & “<a href=""" & theLink & """>” & d & ”</a>”; } else { str=str & d; } str=str & ”</td>”; return str; }

</cfscript>

now that the writeDate() function is built, build the rest of the table.

<table border="0" width="170" align="center">

<tr> <th class=“dateNormal”><strong>s</strong></th> <th class=“dateNormal”><strong>m</strong></th> <th class=“dateNormal”><strong>t</strong></th>

<th class=“dateNormal”><strong>w</strong></th> <th class=“dateNormal”><strong>th</strong></th> <th class=“dateNormal”><strong>f</strong></th>

<th class=“dateNormal”><strong>s</strong></th> </tr>

so here, we loop through the weeks. The loop goes to 6, because in some months that start on Friday or Sat, can actually wrap around the calendar and need 6 rows. i had to figure this out the hard way.

<cfloop from="1" to="6" index="m">
<cfoutput>
<tr>

this is the code that generates the blank spaces before the first of the month, by determining the DayOfWeek() function on the first, and then extrapolating the days needed before it to fill the space.

<cfif #DayOfWeek(thisDate)# GT 1 AND #m# LT 2>
<cfset blankDays=DayOfWeek(thisDate)-1>
<cfloop from="1" to="#blankDays#" index="p">
<td></td>

</cfloop>

now we set the initial weekStart and weekEnd variables. The loop will reset these values each pass through; weekStart will become weekend+1, and so on. we loop through this to generate the days of the month. The <CFIF> statement is there to make sure that we don’t try and write out the remaining spaces at the end of the month (i.e. the 32nd of December).each day gets passed to the writeDate() function along with the results from the earlier query. Here we’re using the valueList() CFfunction to pass the entire querySet (the dates) as a comma delimited list to our function. Our writeDate() function now returns an entire formatted "<td class=dateRelativeClass>day (with link)</td>" string.

<cfset weekStart=1>
<cfset weekEnd=7-blankDays>
</cfif>
<cfloop from="#weekStart#" to="#weekEnd#" index="i"> <cfif DaysInMonth(thisDate) GTE i>

#writeDate(thisYear, thisMonth, i, valueList(getDates.dateList, ”,”))# </cfif> </cfloop>

<cfset weekStart=weekEnd+1> <cfset weekEnd=weekStart+6> </tr> </cfoutput>

</cfloop> </table>

pretty straight forward. The code is still pretty loose; it’s a 1.0 release that was coded quickly late last night. But it works. If I get time, I’ll try and make it more portable and useable. If anyone has any questions or suggestions, drop me a line. My email bloftus@damagedAnimals.com. Good luck!

Dec 12, 2002

6:19 am

This entry has been tagged with: