Reactor Validation Part I
This mini series of a tutorial is intended to help you understand Reactor Validation a little better. This tutorial also expects you to already have some basic knowledge of Reactor and to have it up and running. One of the first major problems I ran into using reactor was validation. I am going to walk you through how you can validate data when creating or updating an object record. I will also walk you through what happens during validation process, in other words how does it actually work. Finally we will walk through how to create your own custom validation methods by extending the base validation object. After the tutorial is over you can download all of the example code as well as a SQL server script (sorry, that is all I have for now). I know some of you may not agree with some of coding methods here but I am throwing this together fast so please forgive me, or leave me a comment and yell at me, haha!
The first thing we are going to do is setup our example application; I am giving it an application name of ReactorValidation, but you can name it whatever. I am also go to set create the reactorFactory object and set it in the application scope. Our example application is going to be a basic contact manager and I am going to provide a list view, add, and edit methods for a contact. Please make sure the admi api or rds password is set below if you do not have a mapping setup. Ok, so onto the code, below is our Application.cfc file.
<cfscript>
this.name = "ReactorValidation";
this.applicationTimeout = createTimeSpan(0,2,0,0);
this.loginStorage = "session";
this.sessionManagement = "true";
this.sessionTimeout = createTimeSpan(0,0,30,0);
</cfscript>
<cffunction name="onApplicationStart" returntype="boolean" access="public">
<cftry>
<cfset application.reactor = createObject("component","reactor.reactorFactory").init(expandPath("reactor.xml"))>
<cfcatch type="reactor.Invalidmapping">
<cfdirectory action="create" directory="#expandPath('.')#\rvdata">
<cfscript>
// Login is always required. adminObj = createObject("component","cfide.adminapi.administrator");
adminObj.login("password");
extensionsObj = createObject("component","cfide.adminapi.extensions");
extensionsObj.setMapping("/rvdata","#expandPath('.')#\rvdata");
</cfscript>
</cfcatch>
</cftry>
<cfreturn true>
</cffunction>
<cffunction name="onApplicationEnd" returnType="void" output="false">
<cfargument name="applicationScope" required="true">
</cffunction>
<cffunction name="onRequestStart" returntype="boolean" access="public">
<cfif NOT structKeyExists(application,"reactor") OR structKeyExists(url,"reinit")>
<cfset onApplicationStart()>
</cfif>
<cfreturn true>
</cffunction>
<cffunction name="onRequest" returnType="void">
<cfargument name="thePage" type="string" required="true">
<cfinclude template="#arguments.thePage#">
</cffunction>
<cffunction name="onRequestEnd" returnType="void" output="false">
<cfargument name="thePage" type="string" required="true">
</cffunction>
<cffunction name="onSessionStart" returntype="void" output="false">
</cffunction>
<cffunction name="onSessionEnd" returnType="void" output="false">
<cfargument name="sessionScope" type="struct" required="true">
<cfargument name="appScope" type="struct" required="false">
</cffunction>
</cfcomponent>
Now we need to setup our Reactor.xml file with the following information. If you need to please download the code so you can setup the datasource and make a mapping for you data folder at this time. If you enter your admin or rds password my Application file should setup your mapping for then all you need to do is create a datasource with the name of ReactorValidation.
<config>
<project value="ReactorValidation" />
<dsn value="ReactorValidation" />
<type value="mssql" />
<mapping value="/rvdata" />
<mode value="development" />
<username value="" />
<password value="" />
</config>
<objects>
<object name="contact" />
</objects>
</reactor>
Now that the application is all setup we are ready to start laying some ground work. First let's create a basic navigation system. The index will be our default file and host our listing of all contacts in the system.
<head>
<title>View Contacts</title>
</head>
<body>
<h1>Contact Manager</h1>
<p>
<a href="index.cfm">View Contacts</a> |
<a href="editContact.cfm">Add Contact</a>
</p>
<body>
<cfset contactGateway = application.reactor.createGateway("contact")>
<cfset contacts = contactGateway.getAll()>
<table border="1">
<tr>
<td><strong>Id</strong></td>
<td><strong>First Name</strong></td>
<td><strong>Last Name</strong></td>
<td><strong>Address</strong></td>
<td><strong>City</strong></td>
<td><strong>State</strong></td>
<td><strong>Zip</strong></td>
<td><strong>Phone</strong></td>
<td><strong>Fax</strong></td>
<td><strong>Email Address</strong></td>
<td><strong>Website</strong></td>
<td> </td>
</tr>
<cfoutput query="contacts">
<tr>
<td>#contactId# </td>
<td>#fname# </td>
<td>#lname# </td>
<td>#address# </td>
<td>#city# </td>
<td>#state# </td>
<td>#zip# </td>
<td>#phone# </td>
<td>#fax# </td>
<td>#emailaddress# </td>
<td>#website# </td>
<td><a href="editContact.cfm?contactId=#contactId#">edit contact</a></td>
</tr>
</cfoutput>
</table>
</body>
</html>
Finally in part one we will create our edit contact page. This page will not actually create or update our contact yet; we will get to that in part II. I know this first installment was a lot of just setting up the application but I promise you that in the coming tutorials we will get into validation.
<head>
<title>Add / Edit Contact</title>
</head>
<body>
<h1>Contact Manager</h1>
<p>
<a href="index.cfm">View Contacts</a> |
<a href="editContact.cfm">Add Contact</a>
</p>
<cfparam name="url.contactId" default="0">
<!--- load the record --->
<cfset contactRecord = application.reactor.createRecord("contact")>
<cfset c = contactRecord.load(contactId=url.contactId)>
<cfparam name="form.fname" default="#c.getFname()#" />
<cfparam name="form.lname" default="#c.getLname()#" />
<cfparam name="form.address" default="#c.getAddress()#" />
<cfparam name="form.city" default="#c.getCity()#"/>
<cfparam name="form.state" default="#c.getState()#"/>
<cfparam name="form.zip" default="#c.getZip()#"/>
<cfparam name="form.phone" default="#c.getPhone()#"/>
<cfparam name="form.fax" default="#c.getFax()#"/>
<cfparam name="form.emailaddress" default="#c.getEmailAddress()#"/>
<cfparam name="form.website" default="#c.getWebsite()#"/>
<br><br>
<cfoutput>
<form action="" method="post" class="edit">
<input type="hidden" name="contactId" value="#url.contactId#">
<fieldset>
<legend>Contact Details</legend>
<p>
<label for="fname">First Name:</label>
<input type="text" name="fname" id="fname" value="#form.fname#">
</p>
<p>
<label for="lname">Last Name:</label>
<input type="text" name="lname" id="lname" value="#form.lname#">
</p>
<p>
<label for="address">Address:</label>
<input type="text" name="address" id="address" value="#form.address#">
</p>
<p>
<label for="city">City:</label>
<input type="text" name="city" id="city" value="#form.city#">
</p>
<p>
<label for="state">State:</label>
<select name="state" id="state" size="1">
<option selected="selected" value="">Select a State</option>
<option value="AL" <cfif form.state eq "AL">selected</cfif>>Alabama</option>
<option value="AK" <cfif form.state eq "AK">selected</cfif>>Alaska</option>
<option value="AZ" <cfif form.state eq "AZ">selected</cfif>>Arizona</option>
<option value="AR" <cfif form.state eq "AR">selected</cfif>>Arkansas</option>
<option value="CA" <cfif form.state eq "CA">selected</cfif>>California</option>
<option value="CO" <cfif form.state eq "CO">selected</cfif>>Connecticut</option>
<option value="DE" <cfif form.state eq "DE">selected</cfif>>Delaware</option>
<option value="FL" <cfif form.state eq "FL">selected</cfif>>Florida</option>
<option value="GA" <cfif form.state eq "GA">selected</cfif>>Georgia</option>
<option value="HI" <cfif form.state eq "HI">selected</cfif>>Hawaii</option>
<option value="ID" <cfif form.state eq "ID">selected</cfif>>Idaho</option>
<option value="IL" <cfif form.state eq "IL">selected</cfif>>Illinois</option>
<option value="IN" <cfif form.state eq "IN">selected</cfif>>Indiana</option>
<option value="IA" <cfif form.state eq "IA">selected</cfif>>Iowa</option>
<option value="KS" <cfif form.state eq "KS">selected</cfif>>Kansas</option>
<option value="KY" <cfif form.state eq "KY">selected</cfif>>Kentucky</option>
<option value="LA" <cfif form.state eq "LA">selected</cfif>>Louisiana</option>
<option value="ME" <cfif form.state eq "ME">selected</cfif>>Maine</option>
<option value="MD" <cfif form.state eq "MD">selected</cfif>>Maryland</option>
<option value="MA" <cfif form.state eq "MA">selected</cfif>>Massachusetts</option>
<option value="MI" <cfif form.state eq "MI">selected</cfif>>Michigan</option>
<option value="MN" <cfif form.state eq "MN">selected</cfif>>Minnesota</option>
<option value="MS" <cfif form.state eq "MS">selected</cfif>>Mississippi</option>
<option value="MO" <cfif form.state eq "MO">selected</cfif>>Missouri</option>
<option value="MT" <cfif form.state eq "MT">selected</cfif>>Montana</option>
<option value="NE" <cfif form.state eq "NE">selected</cfif>>Nebraska</option>
<option value="NV" <cfif form.state eq "NV">selected</cfif>>Nevada</option>
<option value="NH" <cfif form.state eq "NH">selected</cfif>>New Hampshire</option>
<option value="NJ" <cfif form.state eq "NJ">selected</cfif>>New Jersey</option>
<option value="NM" <cfif form.state eq "NM">selected</cfif>>New Mexico</option>
<option value="NY" <cfif form.state eq "NY">selected</cfif>>New York</option>
<option value="NC" <cfif form.state eq "NC">selected</cfif>>North Carolina</option>
<option value="ND" <cfif form.state eq "ND">selected</cfif>>North Dakota</option>
<option value="OH" <cfif form.state eq "OH">selected</cfif>>Ohio</option>
<option value="OK" <cfif form.state eq "OK">selected</cfif>>Oklahoma</option>
<option value="OR" <cfif form.state eq "OR">selected</cfif>>Oregon</option>
<option value="PA" <cfif form.state eq "PA">selected</cfif>>Pennsylvania</option>
<option value="RI" <cfif form.state eq "RI">selected</cfif>>Rhode Island</option>
<option value="SC" <cfif form.state eq "SC">selected</cfif>>South Carolina</option>
<option value="SD" <cfif form.state eq "SD">selected</cfif>>South Dakota</option>
<option value="TN" <cfif form.state eq "TN">selected</cfif>>Tennessee</option>
<option value="TX" <cfif form.state eq "TX">selected</cfif>>Texas</option>
<option value="UT" <cfif form.state eq "UT">selected</cfif>>Utah</option>
<option value="VT" <cfif form.state eq "VT">selected</cfif>>Vermont</option>
<option value="VA" <cfif form.state eq "VA">selected</cfif>>Virginia</option>
<option value="WA" <cfif form.state eq "WA">selected</cfif>>Washington</option>
<option value="WV" <cfif form.state eq "WV">selected</cfif>>West Virginia</option>
<option value="WI" <cfif form.state eq "WI">selected</cfif>>Wisconsin</option>
<option value="WY" <cfif form.state eq "WY">selected</cfif>>Wyoming</option>
</select>
</p>
<p>
<label for="zip">Zip:</label>
<input type="text" name="zip" id="zip" value="#form.zip#">
</p>
<p>
<label for="phone">Phone:</label>
<input type="text" name="phone" id="phone" value="#form.phone#">
</p>
<p>
<label for="fax">Fax:</label>
<input type="text" name="fax" id="fax" value="#form.fax#">
</p>
<p>
<label for="email">Email:</label>
<input type="text" name="email" id="email" value="#form.emailaddress#">
</p>
<p>
<label for="website">Website:</label>
<input type="text" name="website" id="website" value="#form.website#">
</p>
</fieldset>
<p><input type="submit" name="submit" value="Submit"></p>
</form>
</cfoutput>
</body>
</html>
