ColdFusion Contest Entry Examined - Part 5 Welcome to (yet another) entry in the ColdFusion contest. This is turning into a much bigger series than I imagined, but there is so much to learn from looking at how people solve problems. Are people getting bored yet? Check out the last entry which also contains links to all the old entries as well.

Our new entry can be viewed here. The code consists of two files.

contest1.cfm: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <title>Guess My Number Contest</title> </head>

<body> <cfoutput> <form action="contest2.cfm" method="post"> Please, pick a number between 1 and 100 <BR> Your number: <input size="3" maxlength="3" type="text" name="test_number"> <input type="hidden" name="right_number" value="#RandRange(1,100)#"> <input type="hidden" name="total_times" value="1"> <input type="submit" name="GO" value="GO"> </form> </cfoutput> </body> </html>

contest2.cfm: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <title>Guess My Number Contest</title> </head>

<body>

<!-- Is this the number in the good range--> <cfif #form.test_number# GT 100 OR #form.test_number# LT 1> <cfoutput> Your number is not within 1 and 100<BR> <cfset total_times_added = #form.total_times#> <form action="contest2.cfm" method="post"> Please, pick a number between 1 and 100 <BR> Your number: <input size="3" maxlength="3" type="text" name="test_number"> <input type="hidden" name="right_number" value="#form.right_number#"> <input type="hidden" name="total_times" value="#total_times_added#"> <input type="submit" name="GO" value="GO"> </form> </cfoutput> <cfelse>

<!-- Is this the right number --> <cfif form.test_number IS form.right_number> You got it in <cfoutput> #form.total_times# </cfoutput>times. Congratulations!<BR> Wanna play <a href="contest1.cfm">again</a> ??? </cfif>

<!-- Is this the number too high--> <cfif #form.test_number# GT #form.right_number#> <cfoutput> #form.test_number# is too high, please try again<BR> <cfset total_times_added = #form.total_times# + 1> <form action="contest2.cfm" method="post"> Your number: <input size="3" maxlength="3" type="text" name="test_number"> <input type="hidden" name="right_number" value="#form.right_number#"> <input type="hidden" name="total_times" value="#total_times_added#"> <input type="submit" name="GO" value="GO"> </form> </cfoutput> </cfif>

<!-- Is this the number too low--> <cfif form.test_number LT form.right_number> <cfoutput> #form.test_number# is too low, please try again<BR> <cfset total_times_added = #form.total_times# + 1> <form action="contest2.cfm" method="post"> Your number: <input size="3" maxlength="3" type="text" name="test_number"> <input type="hidden" name="right_number" value="#form.right_number#"> <input type="hidden" name="total_times" value="#total_times_added#"> <input type="submit" name="GO" value="GO"> </form> </cfoutput> </cfif> </cfif> </body>

</html>

I think this code sample is an excellent example of a topic I wanted to bring up at a later time - organization, specifically, organization of a form. ColdFusion is a simple language. One of the primary examples of how easy it is can be demonstrated by examining a simple form. What isn't so obvious is how one should set up a form to handle the display of the form, the validation of the form, and finally the result of the successful completion of the form.

Not to be too mean, but I think this code sample shows a perfect example of how not to do things. Let's start with contest1.cfm. This file displays the initial form and posts to contest2. After that, the file isn't used again until you finish the game.

Now look in contest2.cfm. Notice that for the scenario where the user guesses too high or too low, the entire form is duplicated. The same applies for a case where the number was below 1 or above 100. Taken together, the same form is written four times. As you can imagine, when the designer comes in and hands you the spec sheet, you are in trouble.

The primary solution for this is self-posting forms. All this is means is that your form posts to itself, instead of some other file. Here is a pseudo-code example of what I mean:

if(form was submitted) { do a bunch of processing was the form ok? email someone, or store to db, or both }

was there an error? show it

show the form

This isn't terribly complex, but does prevent a lot of the problems the submission above creates. It also makes it a bit simpler to handle since you are dealing with one file, not two. (Of course, some validation may be in outside sources, like CFCs, but let's not worry about that right now.)

Outside of that - there isn't much else to complain about. He does forget to go all the way with validation, but I've made that complaint about all the other entries (and I make that mistake myself). I did notice a few extra uses of # signs where he didn't need them:

<cfif #form.test_number# GT 100 OR #form.test_number# LT 1>

This could be:

<cfif form.test_number GT 100 OR form.test_number LT 1>

The basic rule to remember is - if you aren't in a cfoutput, you typically don't need the pound signs. The only other time you will need them is inside quotes, for example:

<cfset formalName = "Mr. #form.name#">

But even that could be:

<cfset formalName = "Mr. " & form.name>