Finding the last day of the month

Pretty simple equation to show the last day of a month. First, get the first day of next month.

<cfset createdNextMonthDate = CreateDate(year(Now()),month(dateAdd('m',1,Now())),1)>

Then we'll simply subtract one day from that new date.

<cfset lastDayOfMonthForAdStartDate = dateAdd('d',-1,createdNextMonthDate)>

You could put this all into one long line, but I split it up for easier readability.

If you want to set it up as a function, the pass in the date as "datePassed" to the following code, and you will get the last day in that month:

<cffunction name="getLastDayOfMonth" access="public" returntype="date">
<cfargument name="datePassed" type="date" required="Yes">

<cfset createdNextMonthDate = CreateDate(year(arguments.datePassed),month(dateAdd('m',1,arguments.datePassed)),1)>
<cfset lastDayOfMonthForAdStartDate = dateAdd('d',-1,createdNextMonthDate)>

<cfreturn lastDayOfMonthForAdStartDate>

</cffunction>

Creating an easier to read array/structure hybrid

Here's something I came across today that I had never realized or seen before. I created a two dimensional array and filled it with data.

<cfset myArray = ArrayNew(2)>

<cfset myArray[1][1] = "Charles">
<cfset myArray[1][2] = "President">
<cfset myArray[2][1] = "Vicki">
<cfset myArray[2][2] = "VP">
<cfset myArray[3][1] = "Bob">
<cfset myArray[3][2] = "Controller">
<cfset myArray[4][1] = "David">
<cfset myArray[4][2] = "Programmer">

Pretty much standard array practice, right? Well, I started thinking that sometimes its hard to remember which dimension of the array stores what values. So I started thinking about a more logical format I could use and came up with the following:

<cfset myArray = ArrayNew(1)>

<cfset myArray[1]["name"] = "Charles">
<cfset myArray[1]["title"] = "President">
<cfset myArray[2]["name"] = "Vicki">
<cfset myArray[2]["title"] = "VP">
<cfset myArray[3]["name"] = "Bob">
<cfset myArray[3]["title"] = "Controller">
<cfset myArray[4]["name"] = "David">
<cfset myArray[4]["title"] = "Programmer">

Now each value in the array is holding a structure with two values, name and title. I personally find this to be better and allows for easier readability.

To display all values, all I have to do is:

<cfoutput>
   <cfloop from="1" to="arrayLen(myArray)" index="i">
      Name: #myArray[i].name#<br>
      Title: #myArray[i].title#<br>
   </cfloop>
</cfoutput>

For me, its a little easier to read.

onAIR Bus Tour Summer 2007

Last night I went to Adobe's presentation of AIR - Adobe Integrated Runtime. I have to tell you, it was great going, and I'm very excited to see what new apps I can develop.

Oh, and I met Ben Forta as well. Very cool guy. He basically got me started with coldFusion 10 years ago when I bought his first CFWACK book. Thanks Ben.

http://www.adobe.com/go/air

StructAppend, form variables, and the GET method

I made a very silly mistake today. I was putting my url and form variables into the request scope through the application.cfm file

<cfset StructAppend(request, url, "no")>
<cfset StructAppend(request, form, "no")>

Next I had a form page, which was using the GET method to post the form (simplified below).

<form action="formAction.cfm" method="GET">
<input type="hidden" name="reportId" value="#url.reportId#">
<textarea cols="40" rows="3" name="reportComment"></textarea>
<input type="submit" value="Add Comment">
</form>

On the form action page, I was referencing form.reportId, and it was bombing since it did not exist. In fact, the form scope did not exist at all! The values existed in the request scope, so what happened? Did the StructAppend call removes the form scope after it appended it to the request scope? After about five minutes, I remembered that the GET method of posting a form passes all variables through the URL string rather than a form scope.

My mistake was easily fixed by changing the form method to POST, or by simply referencing the REQUEST scope, which I should have been doing in the first place!

Silly mistake. I'm glad nobody knows I did that.

Cold fusion errors - null null, The error occurred on line -1., and java.lang.NullPointerException

Error: null null The error occurred on line -1.

Stack Trace: java.lang.NullPointerException

I have come across these errors in the past and every single one of them is a result of a date function going awry.

One example is a client of mine using a drop down box to "create" a date. They would have a drop down for the month, a drop down for the day (31 days), then one for the year. On the action page, this line of code exists:

#CreateODBCDate(CreateDate(FORM.Year2,FORM.Month2,FORM.Day2))#

So whenever a user would submit an invalid date (04/31/07, 5/d/07, etc.), This line would produce a "null null" error. Cold Fusion has awesome error descriptions, so a description of "null null" leaves you scratching your head. The above error is handled by using simple error catching javascript on the form page and/or a line of server side code on the action page:

<cfif NOT isDate("#Form.Month#-#Form.Day#-#Form.Year#")>
<!--- This is not a date so do something --->
</cfif>

Of course, client side error handling should have been implemented on the form page originally. Try not to forget about CFFORM and Javascript! I implemented some quick and easy client-side error handling, and this page is sitting pretty.

I have come across this error multiple times, and it has always been a date issue. If you're getting a similar error, review those dates!

I like coldFusion's request scope

I've gotten more and more into using the request scope for just about everything lately. Well, maybe not everything, but much more than I used to.

I usually start off with the following line of code in the application file:

<cfset StructAppend(request, url, "no")>
<cfset StructAppend(request, form, "no")>

This allows all url and form variables to be added to the request scope. For many applications, this is a nice convenience. There have been plenty of times when I come across a client that has variables either un-scoped (bad, bad, bad), or they might get the variable from the form or url scope. This solves that problem.

Example: A form submits to a page that shows a report. The report expects many of the variables to come in the Form scope. However, they also have a download link that passes everything in the Url. Now, you can always have a few lines at the top of the page like this:

<cfif isDefined("url.myVariableName")>
<cfset form.myVariableName = url.myVariableName>
</cfif>

But you would have to do this for every variable that could possibly be passed. With the request scope, you can set it in one place, and then reference it.

Another convenience item I like is adding the dsn name to the request scope as well. Again, in the application file.

<cfset request.dsn = "MyDatabaseName">

The greatest benefit with this, is that now this one variable - "request.dsn" - can be used in CFCs, CFMODULE, Custom Tags, etc. I don't have to pass the name of the dsn variable in the arguments scope to a CFC, or attributes scope for a custom tag, as I have seen others do. Very nice.

Of course, there are always circumstances where you may want to have the dsn name passed in, but for the fast majority of circumstances, I gladly omit that variable and reference my request scope!

ColdFusion 8 has arrived!

Well, I just surfed over to Adobe's website and saw that ColdFusion 8 has officially been released!

I'm most psyched about the Ajax integration. I can't wait to use it in a production environment!

Setting a session variable followed by a cflocation

If I want to display a message to the user(not necessarily an error message), I can set the message in the session.ErrorMessage variable, and display it on the following page. This is safe since immediately after I show the user, I remove the message from the session scope.

In the header file of a site I have the following code:

<cfif isDefined("session.ErrorMessage")>
<cfoutput><span class="errorMessage">#session.ErrorMessage#</span></cfoutput>
<cfset structDelete(#session#,"ErrorMessage")>
</cfif>

I started this with only error messages, but have since expanded it for anything. Such as "Your insert statement executed perfectly". Or, "There was a problem with your insert statement"... etc.

Here's the code:

<cfset session.ErrorMessage = "Your session has timed out.">
<cfset structDelete(#session#,"userId")>
<cflocation url="/login.cfm" addtoken="No">

In IE, I've been having a problem with setting the session variable and immediately following it with a cflocation tag. It works fine with Firefox, but with IE, I would get to the new page, and the session.ErrorMessage variable would not exist yet. The NEXT page I would go to would recognize the variable as existing, and display it then, which is pointless and confusing to the user.

The simple answer to this is to turn on clientmanagement in the application.cfm file.

<cfapplication name="MyApplicationName" sessionmanagement="Yes" clientmanagement="Yes" sessiontimeout="#CreateTimeSpan(0,0,90,0)#">

Thats it!

BlogCFC was created by Raymond Camden. This blog is running version 5.8.001.