Micheal,

Here's some code for you, simplified to be generic. Adapt to the
framework/coding style of your choice. This is how i'm doing this at this
point, and i'm pretty happy with it. I hope it's all correct, as i wrote it
up for you, but it should be pretty close.

Here's how i'm doing my BO's ... you could also call this a bean, but cuz i
have validation methods in here, it seemed too glorified to use the term
"bean".

<cfcomponent displayName="Person" hint="I'm a person, more or less"
output="false">

        <cfinclude template="udfs/IsEmail.cfm" />

        <cffunction name="init" access="public" returntype="mappedPath.Person"
output="false">
                <cfargument name="firstName" type="string" required="false" 
default="" />
                <cfargument name="lastName" type="string" required="false" 
default="" />
                <cfargument name="email" type="string" required="false" 
default="" />
                <cfargument name="requiredFields" type="string" required="false"
default="firstName,lastName" hint="I'm a comma delimited list of required
instance variables." />
                <cfset setInstanceFromStruct(arguments) />
                <cfset variables.requiredFields = arguments.requiredFields />
                <cfset variables.invalidFields = "" />
                <cfset variables.missingFields = "" />
                <cfreturn this />
        </cffunction>

        <cffunction name="getInstanceAsStruct" access="public" 
returntype="struct"
output="false">
                <cfset var returnData = StructNew() />
                <cfset returnData.firstName = getFirstName() />
                <cfset returnData.lastName = getLastName() />
                <cfset returnData.email = getEmail() />
                <cfreturn returnData />
        </cffunction>

        <cffunction name="setInstanceFromStruct" access="public"
returntype="mappedPath.Person" output="false">
                <cfargument name="data" required="true" type="struct" hint="The 
struct
containing the data to set." />
                <cfscript>

                        if(structKeyExists(data,"firstName")){
                                setFirstName(data.firstName);
                                }
                        if(structKeyExists(data,"lastName")){
                                setLastName(data.lastName);
                                }
                        if(structKeyExists(data,"email")){
                                setEmail(data.email);
                                }

                </cfscript>
                <cfreturn this />
        </cffunction>


        <cffunction name="validate" access="public" returntype="boolean"
output="no">
                <cfset var valid = true />

                <cfset variables.invalidFields = "" />
                <cfset variables.missingFields = "" />

                <cfloop list="#variables.requiredFields#" index="key">
                        <cfif Len(variables.instance[key]) EQ 0>
                                <cfset variables.missingFields =
listAppend(variables.missingFields,"#key#") />
                                <cfset valid = false>
                        </cfif>
                </cfloop>

                <cfscript>
                                // verify that the email address is properly 
formed
                        if (Len(variables.instance.email)) {
                                if (NOT IsEmail(variables.instance.email)) {
                                        valid = false;
                                        variables.invalidFields = 
listAppend(variables.invalidFields,"email");
                                }
                        }

                </cfscript>

                <cfreturn valid>
        </cffunction>

        <cffunction name="getMissingFields" access="public" returntype="string"
output="false">
                <cfreturn variables.missingFields />
        </cffunction>

        <cffunction name="getInvalidFields" access="public" returntype="string"
output="false">
                <cfreturn variables.invalidFields />
        </cffunction>

        <cffunction name="getValidationIndex" access="public" 
returntype="struct"
output="false"
                hint="I return a structure that indicates the validation 
results for the
interface">
                <cfset var key = "" />
                <cfset var val = StructNew() />

                <cfscript>
                        val.firstName='';
                        val.lastName='';
                        val.email='';
                        val.displayMissingMessage = false;
                        val.displayInvalidMessage = false;
                        val.isValid = true;
                </cfscript>

                <cfif Len(getMissingFields())>
                        <cfloop index="key" list="#getMissingFields()#">
                                <cfset val[key] = "missing"  />
                        </cfloop>
                        <cfset val.displayMissingMessage = true />
                        <cfset val.isValid = false />
                </cfif>

                <cfif Len(getInvalidFields())>
                        <cfloop index="key" list="#getInvalidFields()#">
                                <cfset val[key] = "invalid"  />
                        </cfloop>
                        <cfset val.displayInvalidMessage = true />
                        <cfset val.isValid = false />
                </cfif>
                <cfreturn val />
        </cffunction>

        <cffunction name="getFirstName" access="private" returntype="string"
output="false">
                <cfreturn variables.instance.firstName />
        </cffunction>
        <cffunction name="setFirstName" access="private" returntype="VOID"
output="false">
                <cfargument name="firstName" type="string" required="true" />
                <cfset variables.instance.firstName = arguments.firstName />
        </cffunction>

        <cffunction name="getLastName" access="private" returntype="string"
output="false">
                <cfreturn variables.instance.lastName />
        </cffunction>
        <cffunction name="setLastName" access="private" returntype="VOID"
output="false">
                <cfargument name="lastName" type="string" required="true" />
                <cfset variables.instance.lastName = arguments.lastName />
        </cffunction>

        <cffunction name="getEmail" access="private" returntype="string"
output="false">
                <cfreturn variables.instance.email />
        </cffunction>
        <cffunction name="setEmail" access="private" returntype="VOID"
output="false">
                <cfargument name="email" type="string" required="true" />
                <cfset variables.instance.email = arguments.email />
        </cffunction>

</cfcomponent>


Here's what i call to populate the form to edit ... adapt for a new record

<cfif Not IsDefined("session.Person")>
        <cfset session.Person = CreateObject(
                'component','mappedPath.Person').init() />
</cfif>

<cfif StructKeyExists(url, "idPerson")> <!---  don't read from DB on a
validation loopback --->
        <cfset createObject('component','mappedPath.dao.PersonDAO').init(
                                session.Person).read(idPerson) />
</cfif>

<cfset formData = session.Person.getInstanceAsStruct() />
<cfset val = session.Person.getValidationIndex() />

<cfinclude template="in_editPerson.cfm">

rough sketch of person form

<style>

.formLabel {
        font :bold 12px  Arial, Helvetica, sans-serif;
        color : #086142;
        padding-right: 7px;
}

.missingformLabel {
        font :bold 12px  Arial, Helvetica, sans-serif;
        color : #FF0000;
        padding-right: 6px;
}

.invalidformLabel {
        font :bold 12px  Arial, Helvetica, sans-serif;
        color : #CC0099;
        padding-right: 6px;
}

</style>

<cfif val.displayMissingMessage>
        Please fill in the fields indicated in red.
</cfif>
<cfif val.displayInvalidMessage>
        Please correct the fields indicated in violet.
</cfif>
......
<tr>
        <td height="25" align="right" class="#val.firstName#formLabel"
nowrap="nowrap">First Name</td>
        <td><input type="text" name="firstName" 
value="#formData.firstName#"></td>
</tr>

.... etc ...

Here's what i call when the user clicks the save button ...

<cfset session.Person.setInstanceFromStruct(form) />
<cfset valid = session.Person.validate() />
        <cfif NOT valid>
                <cflocation url="the form url" addtoken="No" />
        </cfif>
<!--- create the DAO --->
<cfset personDAO = createObject('component','mappedPath.dao.PersonDAO') />
<cfset personDAO.init(session.Person, theDatasourceStuff)>

<cfif IsNumeric(form.idPerson)><!--- this is an existing record --->
        <cfset personDAO.update() />
<cfelse>
        <cfset personDAO.create() />
</cfif>


If you need an example of the DAO for this, post back, but it's basically
the same as you'll find on Phil's example code of the mach-ii.info site.

Hope it helps to see a fleshed out example. I know they help me! Time for
another coffee :)

Nando

-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
Behalf Of Dawson, Michael
Sent: Friday, January 28, 2005 4:25 PM
To: [email protected]
Subject: [CFCDev] Validating and Persisting Form Data


This was previously discussed in the "Validation" thread back in
November, but I never really "got it".  This list has several new
members so I would be interested in hearing new solutions, not that I
discount the "elder's" opinions.  ;-)

I have a web-based form and I need to persist the data in a database.  I
also want to validate the data and, if there are errors, reload the form
and display the errors to the user.  (The form is self-posting to make
it easier to re-populate the fields with just-submitted data.)

I also have a simple bean that contains only getters and setters that
equate to the form fields.  The setters are all "typed" (e.g. String,
Numberic, etc.) according to the requirements.  (This is the data that
needs to be validated, eventually, before saving to a database.)

I have a DAO that Creates, Updates and Deletes a single record in the
database.  (This DAO does not validate any data.  It only assumes the
data passedto it has already been validated.)

This is my current situation as mentioned above:
TheForm -> Bean -> DAO -> Database

If I need to validate the data from the form, where would the logic
reside?

Should I use:
TheForm -> TheFormValidationObj -> Bean -> DAO -> Database

Or, do I put the validation in one of the existing layers?  Keep in mind
that I will probably need to reuse some of the validation functions for
other objects.

If anyone could post a fully-working sample of this simple application,
I'm sure many others would greatly appreciate it.

I have a simple working application, but, being new to any OOP thinking,
some things just don't "feel right" to me.

Thanks
M!ke
----------------------------------------------------------
You are subscribed to cfcdev. To unsubscribe, send an email
to [EMAIL PROTECTED] with the words 'unsubscribe cfcdev'
in the message of the email.

CFCDev is run by CFCZone (www.cfczone.org) and supported
by Mindtool, Corporation (www.mindtool.com).

An archive of the CFCDev list is available at
www.mail-archive.com/[email protected]



----------------------------------------------------------
You are subscribed to cfcdev. To unsubscribe, send an email
to [EMAIL PROTECTED] with the words 'unsubscribe cfcdev' 
in the message of the email.

CFCDev is run by CFCZone (www.cfczone.org) and supported
by Mindtool, Corporation (www.mindtool.com).

An archive of the CFCDev list is available at 
www.mail-archive.com/[email protected]

Reply via email to