sign in | join about | help | sitemap
Connecting Tech Pros Worldwide
chromis's Avatar

OOP: Problem implementing a add, edit, delete Contact form


Question posted by: chromis (Member) on August 12th, 2008 01:47 PM
Hi,

I'm writing a contacts section for a cms on a website, I've decided to write the section in OO code. So far I have my Contacts object and a page structure I would use for a procedural site.

/com/Contacts.cfc
Expand|Select|Wrap|Line Numbers
  1. <cfcomponent displayname="Contact" output="false" hint="Contact component">
  2.     <!--- properties: used for self-documentation --->    
  3.     <cfproperty name="dsn" displayname="dsn" hint="Contact id (UUID)" type="string" required="false" />
  4.     <cfproperty name="id" displayname="id" hint="Contact id (UUID)" type="string" required="false" />
  5.     <cfproperty name="firstName" displayname="firstName" hint="The person's first name" 
  6.         type="string" required="false" />
  7.     <cfproperty name="lastName" displayname="lastName" hint="The person's last name" type="string" 
  8.         required="false" />
  9.     <cfproperty name="address" displayname="address" hint="The person's last name" type="string" 
  10.         required="false" />   
  11.     <cfproperty name="email" displayname="email" hint="The person's email address" type="string" 
  12.         required="false" />
  13.     <cfproperty name="telNo" displayname="telNo" hint="The person's telephone number" type="string" 
  14.         required="false" />
  15.  
  16.     <!--- pseudo-constructor: sets default values if init method isn't called --->
  17.     <cfscript>
  18.         // datasource
  19.         variables.dsn = "";    
  20.         // user details
  21.         variable.id = "";        
  22.         variables.firstName = "";            
  23.         variables.lastName = "";
  24.         variables.email = "";
  25.         variables.address = "";        
  26.         variables.telNo = "";            
  27.     </cfscript>
  28.  
  29.     <cffunction name="init" access="public" output="false" returntype="Contact" hint="Constructor for this CFC">
  30.         <!--- take DSN as argument --->
  31.         <cfargument name="dsn" type="string" required="true" hint="The datasource name" />     
  32.         <!--- arguments for the constructor, all of which are optional (no-arg constructor) --->
  33.         <cfargument name="id" displayName="id" type="string" hint="The person's ID (UUID)" 
  34.             required="false" default="" />
  35.         <cfargument name="firstName" displayName="firstName" type="string" hint="The contact's first name" 
  36.             required="false" default="" />
  37.         <cfargument name="lastName" displayName="lastName" type="string" hint="The contact's last name" 
  38.             required="false" default="" />
  39.         <cfargument name="address" displayName="address" type="string" hint="The contact's address" 
  40.             required="false" default="" />            
  41.         <cfargument name="email" displayName="email" type="string" hint="The contact's email address" 
  42.             required="false" default="" />
  43.         <cfargument name="telNo" displayName="telNo" type="string" hint="The contact's phone 
  44.             number" required="false" default="" />
  45.         <!--- call the setters for each of the Person attributes and pass in the arguments --->
  46.         <cfscript>
  47.             setId(arguments.id);
  48.             setFirstName(arguments.firstName);
  49.             setLastName(arguments.lastName);
  50.             setAddress(arguments.address);
  51.             setEmail(arguments.email);
  52.             setTelNo(arguments.telNo);
  53.         </cfscript>
  54.  
  55.         <!--- return this CFC --->
  56.         <cfreturn this />
  57.     </cffunction>
  58.  
  59.     <!--- getters and setters (aka accessors and mutators) --->
  60.     <cffunction name="getFirstName" access="public" output="false" returntype="string">
  61.         <cfreturn variables.firstName />
  62.     </cffunction>
  63.  
  64.     <cffunction name="setFirstName" access="public" output="false" returntype="void">
  65.         <cfargument name="firstName" type="string" required="true" />
  66.         <cfset variables.firstName = arguments.firstName />
  67.     </cffunction>
  68.  
  69.     <cffunction name="getLastName" access="private" output="false" returntype="string">
  70.         <cfreturn variables.lastName />
  71.     </cffunction>
  72.  
  73.     <cffunction name="setLastName" access="public" output="false" returntype="void">
  74.         <cfargument name="lastName" type="string" required="true" />
  75.         <cfset variables.lastName = arguments.lastName />
  76.     </cffunction>
  77.  
  78.     <cffunction name="getEmail" access="public" output="false" returntype="string">
  79.         <cfreturn variables.email />
  80.     </cffunction>
  81.  
  82.     <cffunction name="setEmail" access="public" output="false" returntype="void">
  83.         <cfargument name="email" type="string" required="true" />
  84.         <cfset variables.email = arguments.email />
  85.     </cffunction>
  86.  
  87.     <cffunction name="getAddress" access="public" output="true" returntype="string">
  88.         <cfreturn variables.address />
  89.     </cffunction>
  90.  
  91.     <cffunction name="setAddress" access="public" output="false" returntype="void">
  92.         <cfargument name="address" type="string" required="true" />
  93.         <cfset variables.address = arguments.address />
  94.     </cffunction>    
  95.  
  96.     <cffunction name="getTelno" access="public" output="true" returntype="string">
  97.         <cfreturn variables.telNo />
  98.     </cffunction>
  99.  
  100.     <cffunction name="setTelno" access="public" output="false" returntype="void">
  101.         <cfargument name="telNo" type="string" required="true" />
  102.         <cfset variables.telNo = arguments.telNo />
  103.     </cffunction>   
  104.  
  105.     <cffunction name="getID" access="public" output="true" returntype="string">
  106.         <cfreturn variables.ID />
  107.     </cffunction>
  108.  
  109.     <cffunction name="setID" access="public" output="false" returntype="void">
  110.         <cfargument name="id" type="string" required="true" />
  111.         <cfset variables.id = arguments.id />
  112.     </cffunction>        
  113.  
  114.     <!--- CRUD - Persistent data functions --->
  115.     <cffunction name="create" access="public" output="false" returntype="boolean" hint="CRUD Method">
  116.         <cfargument name="contact" type="com.Contact" required="true" />
  117.  
  118.         <cftransaction>
  119.             <cfquery name="qCreate" datasource="#variables.dsn#">
  120.                 INSERT INTO
  121.                 contacts
  122.                 (
  123.                 firstName,
  124.                 lastName,
  125.                 address,                
  126.                 email,
  127.                 telNo
  128.                 )
  129.                 VALUES
  130.                 (
  131.                 <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.car.getFirstname()#" />,
  132.                 <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.car.getLastname()#" />,
  133.                 <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.car.getAddress()#" />,
  134.                 <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.car.getEmail()#" />,
  135.                 <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.car.getTelno()#" />                                                             
  136.                 )
  137.                 SELECT @@IDENTITY AS newID
  138.             </cfquery>
  139.               <cfset arguments.contact.setID(qCreate.newID) />
  140.         </cftransaction>
  141.  
  142.       </cffunction>  
  143.      <cffunction name="read" access="public" returntype="Void" output="false" hint="CRUD method">
  144.         <cfargument name="contact" type="com.Contact" required="true" />
  145.         <cfargument name="contactID" type="String" required="yes" />
  146.  
  147.         <cfset var qRead = 0 />
  148.  
  149.         <cfquery name="qRead" datasource="#variables.dsn#">
  150.         SELECT
  151.             firstName,
  152.             lastName,
  153.             address,
  154.             email,
  155.             telNo
  156.         FROM
  157.             contacts
  158.         WHERE
  159.             id = <cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.contactID#" />
  160.         </cfquery>
  161.  
  162.         <cfif qRead.RecordCount>
  163.             <cfset arguments.contact.setID(arguments.contactID) />
  164.             <cfset arguments.contact.setFirstname(qRead.firstname) />
  165.             <cfset arguments.contact.setLastname(qRead.lastname) />
  166.             <cfset arguments.contact.setAddress(qRead.address) />
  167.             <cfset arguments.contact.setEmail(qRead.email) />            
  168.             <cfset arguments.contact.setTelno(qRead.telno) />                           
  169.         <cfelse>
  170.             <cfthrow type="emptyRecordset" errorcode="Contact.read.emptyRecordset" message="Contact with ContactID #arguments.contactID# not found" />
  171.         </cfif>
  172.   </cffunction>
  173.   <cffunction name="update" access="public" returntype="Void" output="false" hint="CRUD method">
  174.     <cfargument name="contact" type="com.Contact" required="yes" />
  175.  
  176.     <cfquery name="qUpdate" datasource="#variables.dsn#">
  177.         UPDATE
  178.             contacts
  179.         SET
  180.             firstName = <cfqueryparam cfsqltype="cf_sql_varchar" value="#contact.getFirstname()#" />,
  181.             lastName = <cfqueryparam cfsqltype="cf_sql_varchar" value="#contact.getLastname()#" />,
  182.             address = <cfqueryparam cfsqltype="cf_sql_varchar" value="#contact.getAddress()#" />,
  183.             email = <cfqueryparam cfsqltype="cf_sql_varchar" value="#contact.getEmail()#" />,
  184.             telNo = <cfqueryparam cfsqltype="cf_sql_varchar" value="#contact.getTelno()#" />
  185.         WHERE
  186.             id = <cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.contact.getID()#" />
  187.     </cfquery>
  188.  
  189.   </cffunction>
  190.  
  191.   <cffunction name="delete" access="public" returntype="Void" output="false" hint="CRUD method">
  192.     <cfargument name="contact" type="com.Contact" required="yes" />
  193.  
  194.     <cfquery name="qDeletePresenter" datasource="#variables.dsn#">
  195.     DELETE FROM
  196.       contacts
  197.     WHERE
  198.       id = <cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.contact.getID()#" />
  199.     ;
  200.     </cfquery>
  201.  
  202.   </cffunction>
  203.  
  204.   <!--- commit methods --->
  205.   <cffunction name="commit" access="public" returntype="Void" output="false" hint="commit method">
  206.     <cfargument name="car" type="com.Contact" required="yes" />
  207.  
  208.     <cfquery name="qExists" datasource="#variables.dsn#">
  209.     SELECT
  210.       id
  211.     FROM
  212.       contacts
  213.     WHERE
  214.       id = <cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.contact.getId()#" />
  215.     ;
  216.     </cfquery>
  217.  
  218.     <cfif qExists.recordcount>
  219.       <cfset this.update(arguments.contact) />
  220.     <cfelse>
  221.       <cfset this.create(arguments.contact) />
  222.     </cfif>
  223.  
  224.   </cffunction>
  225.  
  226.   <!--- public methods --->
  227.   <cffunction name="validate" access="public" returntype="Struct" output="false" hint="I validate all properties in the Contact Object">
  228.     <cfscript>
  229.         // initialize variables
  230.         var errors = StructNew();
  231.  
  232.         // validate values
  233.         if (getFirstName() EQ "") {
  234.             errors.firstName = "The first name field is required";
  235.         }
  236.  
  237.         if (getLastName() EQ "") {
  238.             errors.lastName = "The last name field is required";
  239.         }
  240.  
  241.         if (getAddress() EQ "") {
  242.             errors.address = "The address field is required";
  243.         }
  244.  
  245.         if (getTelno() EQ "") {
  246.             errors.telNo = "The telephone number field is required";
  247.         }
  248.  
  249.         // if we got an email address, validate the format
  250.         if (getEmail() NEQ "") {
  251.             if (Not isEmail(getEmail())) {
  252.                 errors.email = "Your email address is not valid. Please re-enter.";
  253.             }
  254.         }
  255.         else {
  256.             errors.email = "The email field is required.";        
  257.         }
  258.         return errors;
  259.     </cfscript>  
  260.   </cffunction>
  261.     <!--- function to validate email --->
  262.     <cffunction name="isEmail" access="public" output="false" returntype="boolean" hint="Validates 
  263.         the format of the string passed in to see if it's a valid email address">
  264.         <cfargument name="email" type="string" required="true" />
  265.  
  266.         <cfscript>
  267.             if (REFindNoCase("^['_a-z0-9-]+(\.['_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*\.(([a-z]{2,3})|(aero|coop|info|museum|name))$", 
  268.                 arguments.email)) {
  269.                 return true;
  270.             } else {
  271.                 return false;
  272.             }
  273.         </cfscript>
  274.     </cffunction>  
  275. </cfcomponent>


I usually structure my pages like this:

index.cfm - Contains case statements for url.action
display/add.cfm
display/edit.cfm
display/delete.cfm
com/contacts.cfc

Then I have the usual header and footer includes.

What I'm struggling with is how to structure my pages and deal with the validation of form data. The following is a structure I've kind of cobbled together, based on the idea that there should only be one form for adding / editing (creating/updating) and a cfm for processing the data sent from the form.

index.cfm - Contains case statements for url.action
display/form.cfm - Displays form for creating, updating of contacts.
display/create.cfm - Creates contact object from form elements and adds contact to database
display/update.cfm - Updates contact object from form elements

Has anyone got any examples of how they structure their OO form pages? I'm at the beginning of the CFOO curve and a bit confused!

Thanks,

Chromis
8 Answers Posted
chromis's Avatar
chromis August 13th, 2008 10:37 AM
Member - 80 Posts
#2: Re: OOP: Problem implementing a add, edit, delete Contact form

Ok, I can't figure out how to delete this post so I'll post a new one about where I've got up to.
acoder's Avatar
acoder August 14th, 2008 10:07 AM
Site Moderator - 12,587 Posts
#3: Re: OOP: Problem implementing a add, edit, delete Contact form

Quote:
Originally Posted by chromis
What I'm struggling with is how to structure my pages and deal with the validation of form data.
The problem with validation in COOP (Coldfusion OOP) is that you have two answers that you don't like to hear: "it depends" and "there's no one right answer". Here's an old link, but it gives you an idea of what I mean. This link may help a little. You may also want to look at the series of blog posts on form validation on bennadel.com.
chromis's Avatar
chromis August 18th, 2008 10:09 AM
Member - 80 Posts
#4: Re: OOP: Problem implementing a add, edit, delete Contact form

Hi acoder,

Thanks for the links I'll have a look into these. I was going to code the website I'm creating in a OO fashion, though it's taking too long to work out the best way of doing things. I guess I'll have to keep this as a side project until I'm confident enough with it.

Thanks.

Chromis
acoder's Avatar
acoder August 18th, 2008 11:14 AM
Site Moderator - 12,587 Posts
#5: Re: OOP: Problem implementing a add, edit, delete Contact form

If you've never programmed in OO before, it can be a bit of a steep learning curve, but I'm sure you'll get there. If you're trying to stick to MVC as well, it can be even more difficult at first, though it'll be beneficial in the long run. Only use MVC for medium to large projects; there's no need for the complexity for small projects.
chromis's Avatar
chromis August 18th, 2008 12:45 PM
Member - 80 Posts
#6: Re: OOP: Problem implementing a add, edit, delete Contact form

Ok cool I'll remember that. What I struggle with is how to structure the pages for the smaller projects, is the structure I use above ok or do i need to create controller objects for dealing with page requests such as index.cfm?action=edit?

Any chance you could give me an example of a small project you have worked on so I can see how you do things?
acoder's Avatar
acoder August 18th, 2008 07:14 PM
Site Moderator - 12,587 Posts
#7: Re: OOP: Problem implementing a add, edit, delete Contact form

You could use a DAO bean. This is a good series of articles, in particular you may find this part useful.
chromis's Avatar
chromis August 19th, 2008 02:05 PM
Member - 80 Posts
#8: Re: OOP: Problem implementing a add, edit, delete Contact form

Hi acoder,

Thanks I'd actually been reading through that article. I'm building a good list of resources though now, ben nadel and sean corfield have good blogs that i've been looking through. It's just going to take some time i guess.

Thanks,

Chromis
acoder's Avatar
acoder August 19th, 2008 03:04 PM
Site Moderator - 12,587 Posts
#9: Re: OOP: Problem implementing a add, edit, delete Contact form

Yes, those are good blogs as well as Raymond Camden's and a few others.

Anyway, good luck on the OOP quest! :)
Reply
Not the answer you were looking for? Post your question . . .
196,994 members ready to help you find a solution.
Join Bytes.com

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over 196,994 network members.
Post your question now . . .
It's fast and it's free

Popular Articles

Top Coldfusion Contributors