Self-submitting Form - Exercise

Contact Us or call 1-877-932-8228
Self-submitting Form - Exercise

Self-submitting Form

Duration: 20 to 30 minutes.

In the solution in the last exercise, when there is an error in the form, all the form data gets lost. This is not ideal. In this exercise, you will create a page that contains both the form and the processing code. We use the CGI.SCRIPT_NAME variable, which holds the name of the current file, as our form action. The page works as follows:

If the form has not yet been submitted (e.g, on the first visit to the page), the page outputs the form.

Likewise, if the form has been submitted with errors, the page re-outputs the form, but keeps any valid values that were entered.

If the form has been submitted with no errors, we'll process the form data and output the form showing the entered valued.

  1. Open FlowControl/Exercises/CalculatorSelfProcess.cfm in your editor.
  2. Much of the code is already written. Review it to make sure you have a good understanding of what's going on.
    • Notice the hidden field named "submitted" You can use this field to check to see if the form has been submitted.
  3. In the comments of the code you will find three tasks to complete.
  4. After completing the tasks, open FlowControl/Exercises/CalculatorSelfProcess.cfm in your browser and test your solution.

Code Sample:

FlowControl/Exercises/CalculatorSelfProcess.cfm
<html>
<head>
<title>Marathon Time Calculator</title>
</head>
<body> 
	<h1>Marathon Time Calculator</h1> 
	<!---
	TASK 1: Write if condition that checks if form was
	submitted and that there were no errors.
	---> 
	<cfif WRITE_CONDITION_HERE>
		<!---Set Variables---> 
		<cfset Marathon = 26.2> 
		<cfset Conversion = .62> 
		<!---Check units---> 
		<cfif FORM.units EQ "mph"> 
			<!---Specify which option should be selected---> 
			<cfset mphselected=" selected"> 
			<cfset kphselected=""> 
			<cfset yourmarathontime = Marathon/FORM.yourspeed> 
			<cfset friendmarathontime = Marathon/FORM.friendspeed> 
			<cfelse> 
			<!---Specify which option should be selected---> 
			<cfset mphselected=""> 
			<cfset kphselected=" selected"> 
			<cfset yourmarathontime = Marathon/Conversion/FORM.yourspeed> 
			<cfset friendmarathontime = Marathon/Conversion/FORM.friendspeed> 
		</cfif> 
		<cfset yourhours = Int(yourmarathontime)> 
		<cfset yourminutes = (yourmarathontime * 60) MOD 60> 
		<cfset friendhours = Int(friendmarathontime)> 
		<cfset friendminutes = (friendmarathontime * 60) MOD 60> 
		<cfoutput> #FORM.yourname#, at #FORM.yourspeed# #FORM.units#, you would run a marathon in #yourhours# hours and #yourminutes# minutes.<br> 
			At #FORM.friendspeed# #FORM.units#, #FORM.friendname# would run a marathon in #friendhours# hours and #friendminutes# minutes.<br> 
			<!---
			TASK 2: Write a nested if condition that determines
			who will win and by how many minutes.  The output to the
			browser should read:
			"You would beat Marylin by 10.3 minutes." OR
			"Marylin would beat you by 10.3 minutes." OR
			"Marylin and you would finish at the same time."
			---> 
			<p>Form processed at #TimeFormat(Now(),"h:mmtt")# on #DateFormat(Now(),"mmmm d, yyyy")#.</p> 
		</cfoutput> 
		<cfelseif isDefined("FORM.submitted")> 
		<!---Checks if form was submitted with errors.---> 
		<p class="errors">All fields are required.</p> 
		<p class="errors">Speeds must be numeric.</p> 
	</cfif> 
			<!---
			TASK 3: Use <cfparam> to create default values
			for the Form variables of empty strings.
			Replace all instances of "FOO" in the form below
			with appropriate values.
			You will also need to create default values for
			mphselected and kphselected.
			--->
	<cfoutput> 
		<form method="post" action="#CGI.SCRIPT_NAME#"> 
			<input type="hidden" name="submitted" value="true">
			<table> 
				<tr> 
					<td>Your Name:</td> 
					<td><input name="yourname" value="FOO"
					type="text" size="30" maxlength="50"></td> 
				</tr> 
				<tr> 
					<td>Your Speed:</td> 
					<td> <input name="yourspeed" value="FOO"
								type="text" size="4" maxlength="5"> </td> 
				</tr> 
				<tr valign="top"> 
					<td>Friend's Name:</td> 
					<td><input name="friendname" value="FOO"
								type="text" size="30" maxlength="50"> </td> 
				</tr> 
				<tr> 
					<td>Friend's Speed:</td> 
					<td> <input name="friendspeed" value="FOO"
								type="text" size="4" maxlength="5"> </td> 
				</tr> 
				<tr> 
					<td>Units</td> 
					<td> <select name="units"> 
							<option value="mph"#mphselected#>MPH</option> 
							<option value="kph"#kphselected#>KPH</option> 
						</select> </td> 
				</tr> 
				<tr> 
					<td colspan="2" align="right"> <input type="submit" value="Calculate"> </td> 
				</tr> 
			</table> 
		</form> 
	</cfoutput>
</body>
</html>

In your solution, the user probably gets no feedback if he submits the form with errors. Add an <cfelseif> block to the outer <cfif> block that checks to see if the form was submitted with errors and gives the user feedback if it was.

Solution:

FlowControl/Solutions/CalculatorSelfProcess.cfm
<html>
<head>
<title>Marathon Time Calculator</title>
</head>

<body>

<h1>Marathon Time Calculator</h1>

<cfif 	isDefined("FORM.submitted") AND
			( FORM.yourname NEQ ""
			AND FORM.friendname NEQ ""
			AND isNumeric(FORM.yourspeed)
			AND isNumeric(FORM.friendspeed) )>
			
	<!---Set Variables--->
	<cfset Marathon = 26.2>
	<cfset Conversion = .62>
	
	<!---Check units--->
	<cfif FORM.units EQ "mph">
		<!---Specify which option should be selected--->
		<cfset mphselected=" selected">
		<cfset kphselected="">
		<cfset yourmarathontime = Marathon/FORM.yourspeed>
		<cfset friendmarathontime = Marathon/FORM.friendspeed>
	<cfelse>
		<!---Specify which option should be selected--->
		<cfset mphselected="">
		<cfset kphselected=" selected">
		<cfset yourmarathontime = Marathon/Conversion/FORM.yourspeed>
		<cfset friendmarathontime = Marathon/Conversion/FORM.friendspeed>
	</cfif>
	
	<cfset yourhours = Int(yourmarathontime)>
	<cfset yourminutes = (yourmarathontime * 60) MOD 60>
	<cfset friendhours = Int(friendmarathontime)>
	<cfset friendminutes = (friendmarathontime * 60) MOD 60>
	
	<cfoutput>
	#FORM.yourname#, at #FORM.yourspeed# #FORM.units#,
	you would run a marathon in #yourhours#
	hours and #yourminutes# minutes.<br>
	
	At #FORM.friendspeed# #FORM.units#, #FORM.friendname# would
	run a marathon in #friendhours# hours
	and #friendminutes# minutes.<br>
	
	<cfif yourmarathontime LT friendmarathontime>
		<cfset diff = (friendmarathontime - yourmarathontime) * 60>
		You would beat #FORM.friendname# by #Int(diff)# minutes.
	<cfelseif friendmarathontime LT yourmarathontime>
		<cfset diff = (yourmarathontime - friendmarathontime) * 60>
		#FORM.friendname# would beat you by #Int(diff)# minutes.
	<cfelse>
		#FORM.friendname# and you would finish at the same time.
	</cfif>
	
	<p>Form processed at #TimeFormat(Now(),"h:mmtt")# on
		#DateFormat(Now(),"mmmm d, yyyy")#.</p>
	</cfoutput>
	
</cfif>

<cfparam name="FORM.yourname" default="">
<cfparam name="FORM.friendname" default="">
<cfparam name="FORM.yourspeed" default="">
<cfparam name="FORM.friendspeed" default="">
<cfparam name="mphselected" default=" selected">
<cfparam name="kphselected" default="">

<cfoutput>
<form method="post" action="#CGI.SCRIPT_NAME#">
<input type="hidden" name="submitted" value="true">
<table>
<tr>
	<td>Your Name:</td>
	<td><input name="yourname" value="#FORM.yourname#"
					type="text" size="30" maxlength="50"></td>
</tr>
<tr>
	<td>Your Speed:</td>
	<td>
		<input name="yourspeed" value="#FORM.yourspeed#"
								type="text" size="4" maxlength="5">
	</td>
</tr>
<tr valign="top">
	<td>Friend's Name:</td>
	<td><input name="friendname" value="#FORM.friendname#"
								type="text" size="30" maxlength="50">
	</td>
</tr>
<tr>
	<td>Friend's Speed:</td>
	<td>
		<input name="friendspeed" value="#FORM.friendspeed#"
								type="text" size="4" maxlength="5">
	</td>
</tr>
<tr>
	<td>Units</td>
	<td>
		<select name="units">
			<option value="mph"#mphselected#>MPH</option>
			<option value="kph"#kphselected#>KPH</option>
		</select>
	</td>
</tr>
<tr>
	<td colspan="2" align="right">
		<input type="submit" value="Calculate">
	</td>
</tr>
</table>
</form>
</cfoutput>
</body>
</html>

Challenge Solution:

FlowControl/Solutions/CalculatorSelfProcess-challenge.cfm
<html>
<head>
<title>Marathon Time Calculator</title>
</head>

<body>

<h1>Marathon Time Calculator</h1>

<cfif isDefined("FORM.submitted") AND
			( FORM.yourname NEQ ""
			AND FORM.friendname NEQ ""
			AND isNumeric(FORM.yourspeed)
			AND isNumeric(FORM.friendspeed) )>
---- C O D E   O M I T T E D ----
<!---CHALLENGE SOLUTION--->
<cfelseif isDefined("FORM.submitted")>
	<!---Checks if form was submitted with errors.--->
	<p class="errors">All fields are required.</p>
	<p class="errors">Speeds must be numeric.</p>
<!---END CHALLENGE SOLUTION--->
	
</cfif>
---- C O D E   O M I T T E D ----

Next