Reusing Forms


You can now add to as well as update and delete from your Films table. But what if you need to change the form? What if you needed to add a field, or change validation, or update colors? Any changes that need to be made to the Add form also must be made to the Update form.

With all the effort you have gone to in the past few chapters to prevent any duplication of effort, this seems counterproductive.

Indeed it is.

The big difference between an Add and an Update form is whether the fields are pre-filled to show current values. Using ColdFusion conditional expressions, you can create a single form that can be used for both adding and updating data.

To do this, all you need is a way to conditionally include the value attribute in <input>. After all, look at the following two <input> statements:

 <input type="text" name="MovieTitle"> <input type="text" name="MovieTitle" value="#MovieTitle#"> 

The first <input> is used for new data; there is no pre-filled value. The second is for editing, and thus the field is populated with an initial value.

Therefore, it wouldn't be hard to create <input> fields with <cfif> statements embedded in them, conditionally including the value. Look at the following code:

 <input type="text" name="MovieTitle"  <cfif IsDefined("URL.FilmID")>  value="#MovieTitle#"  </CFIF> > 

This <input> field includes the value attribute only if the FilmID was passed (meaning that this is an edit operation as opposed to an add operation). Using this technique, a single form field can be used for both adds and edits.

This is perfectly valid code, and this technique is quite popular. The only problem with it is that the code can get very difficult to read. All those embedded <cfif> statements, one for every row, make the code quite complex. There is a better solution.

value can be an empty string, the attribute value="" is perfectly legal and valid. So why not always use value, but conditionally populate it? The best way to demonstrate this is to try it, so Listing 14.13 contains the code for edit1.cfma new dual-purpose form.

Listing 14.13. edit1.cfmCombination Insert and Update Form
 <!--- Name:        edit1.cfm Author:      Ben Forta (ben@forta.com) Description: Dual purpose form demo Created:     12/21/04 ---> <!--- Check that FilmID was provided ---> <!--- If yes, edit, else add ---> <cfset EditMode=IsDefined("URL.FilmID")> <!--- If edit mode then get row to edit ---> <cfif EditMode>  <!--- Get the film record --->  <cfquery datasource="ows" name="film">  SELECT FilmID, MovieTitle, PitchText,         AmountBudgeted, RatingID,         Summary, ImageName, DateInTheaters  FROM Films  WHERE FilmID=#URL.FilmID#  </cfquery>  <!--- Save to variables --->  <cfset MovieTitle=Trim(film.MovieTitle)>  <cfset PitchText=Trim(film.PitchText)>  <cfset AmountBudgeted=Int(film.AmountBudgeted)>  <cfset RatingID=film.RatingID>  <cfset Summary=Trim(film.Summary)>  <cfset ImageName=Trim(film.ImageName)>  <cfset DateInTheaters=DateFormat(film.DateInTheaters, "MM/DD/YYYY")>  <!--- Form text --->  <cfset FormTitle="Update a Movie">  <cfset ButtonText="Update"> <cfelse>  <!--- Save to variables --->  <cfset MovieTitle="">  <cfset PitchText="">  <cfset AmountBudgeted="">  <cfset RatingID="">  <cfset Summary="">  <cfset ImageName="">  <cfset DateInTheaters="">  <!--- Form text --->  <cfset FormTitle="Add a Movie">  <cfset ButtonText="Insert"> </cfif> <!--- Get ratings ---> <cfquery datasource="ows" name="ratings"> SELECT RatingID, Rating FROM FilmsRatings ORDER BY RatingID </cfquery> <!--- Page header ---> <cfinclude template="header.cfm"> <!--- Add/update movie form ---> <cfform action="edit2.cfm"> <cfif EditMode>  <!--- Embed primary key as a hidden field --->  <cfoutput>  <input type="hidden" name="FilmID" value="#Film.FilmID#">  </cfoutput> </cfif> <table align="center" bgcolor="orange">  <tr>   <th colspan="2">    <cfoutput>    <font size="+1">#FormTitle#</font>    </cfoutput>   </th>  </tr>  <tr>   <td>    Movie:   </td>   <td>    <cfinput type="Text"             name="MovieTitle"             value="#MovieTitle#"             message="MOVIE TITLE is required!"             required="Yes"             validateAt="onSubmit,onServer"             size="50"             maxlength="100">   </td>  </tr>  <tr>   <td>    Tag line:   </td>   <td>    <cfinput type="Text"             name="PitchText"             value="#PitchText#"             message="TAG LINE is required!"             required="Yes"             validateAt="onSubmit,onServer"             size="50"             maxlength="100">   </td>  </tr>  <tr>   <td>    Rating:   </td>   <td>    <!--- Ratings list --->    <select name="RatingID">     <cfoutput query="ratings">      <option value="#RatingID#"       <cfif ratings.RatingID IS VARIABLES.RatingID>        selected       </cfif>>       #Rating#</option>     </cfoutput>    </select>   </td>  </tr>  <tr>   <td>    Summary:   </td>   <td>    <cfoutput>    <textarea name="summary"              cols="40"              rows="5"              wrap="virtual">#Summary#</textarea>    </cfoutput>   </td>  </tr>  <tr>   <td>    Budget:   </td>   <td>    <cfinput type="Text"             name="AmountBudgeted"             value="#AmountBudgeted#"             message="BUDGET must be a valid numeric amount!"             required="NO"             validate="integer"             validateAt="onSubmit,onServer"             size="10"             maxlength="10">   </td>  </tr>  <tr>   <td>    Release Date:   </td>   <td>    <cfinput type="Text"             name="DateInTheaters"             value="#DateInTheaters#"             message="RELEASE DATE must be a valid date!"             required="NO"             validate="date"             validateAt="onSubmit,onServer"             size="10"             maxlength="10">   </td>  </tr>  <tr>   <td>    Image File:   </td>   <td>    <cfinput type="Text"             name="ImageName"             value="#ImageName#"             required="NO"             size="20"             maxlength="50">   </td>  </tr>  <tr>   <td colspan="2" align="center">    <cfoutput>    <input type="submit" value="#ButtonText#">    </cfoutput>   </td>    </tr> </table> </cfform> <!--- Page footer ---> <cfinclude template="footer.cfm"> 

The code first determines whether the form will be used for an Add or an Update. How can it know this? The difference between how the two are called is in the URLwhether FilmID is passed. The code <cfset EditMode=IsDefined("URL.FilmID")> created a variable named EditMode, which will be TRUE if URL.FilmID exists and FALSE if not. This variable can now be used as necessary throughout the page.

Next comes a <cfif> statement. If editing (EditMode is trUE) then a <cfquery> is used to retrieve the current values. The fields retrieved by that <cfquery> are saved in local variables using multiple <cfset> tags. No <cfquery> is used if it is an insert operation, but <cfset> is used to create empty variables.

By the time the </cfif> has been reached, a set of variables has been created. They'll either contain values (from the Films table) or be empty. Either way, they're usable as value attributes in <input> and <cfinput> tags.

Look at the <cfinput> fields themselves. You'll notice that no conditional code exists within them, as it did before. Instead, every <input> tag has a value attribute, regardless of whether this is an insert or an update. The value in the value attribute is a ColdFusion variablea variable that is set at the top of the template, not a database field.

The rest of the code in the template uses these variables, without needing any conditional processing. Even the page title and submit button text can be initialized in variables this way, so <cfif> tags aren't necessary for them, either.

The primary key, embedded as a hidden field, is necessary only if a movie is being edited, so the code to embed that field is enclosed within a <cfif> statement:

 <cfif EditMode>  <!--- Embed primary key as a hidden field --->  <cfoutput>  <input type="hidden" name="FilmID" value="#Film.FilmID#">  </cfoutput> </cfif> 

Even the form header at the top of the page and the text of the submit button are populated using variables. This way, the <form> is completely reusable:

 <INPUT TYPE="submit" VALUE="#ButtonText#"> 

This form is submitted to the same action page regardless of whether data is being added or updated. Therefore, the action page also must support both additions and updates. Listing 14.14 contains the new action template, edit2.cfm.

Listing 14.14. edit2.cfmCombination Insert and Update Page
 <!--- Name:        edit2.cfm Author:      Ben Forta (ben@forta.com) Description: Dual purpose form demo Created:     12/21/04 ---> <!--- Insert or update? ---> <cfset EditMode=IsDefined("FORM.FilmID")> <cfif EditMode>  <!--- Update movie --->  <cfupdate datasource="ows" tablename="Films">  <cfset action="updated"> <cfelse>  <!--- Add movie --->  <cfinsert datasource="ows" tablename="Films">  <cfset action="added"> </cfif> <!--- Page header ---> <cfinclude template="header.cfm"> <!--- Feedback ---> <cfoutput> <h1>Movie #FORM.MovieTitle# #action#</h1> </cfoutput> <!--- Page footer ---> <cfinclude template="footer.cfm"> 

This code also first determines the EditMode, this time by checking for a FORM field named FilmID (the hidden form field). If EditMode is trUE, a <cfupdate> is used to update the row; otherwise, a <cfinsert> is used to insert it. The same <cfif> statement also is used to set a variable that is used later in the page when providing user feedback.

It's clean, simple, and reusable.



Macromedia Coldfusion MX 7 Web Application Construction Kit
Macromedia Coldfusion MX 7 Web Application Construction Kit
ISBN: 321223675
EAN: N/A
Year: 2006
Pages: 282

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net