Article

Easy Rich Internet Applications With ColdFusion 8

Page: 1 2 3

Creating the Form

Here's our code for creating a user form:

<cfparam name="url.userId" default="" />  
 
<cfset user = createObject("component","com.user.UserService").getUser(url.userid) />  
 
 
<cfform name="userForm">  
 <cfinput type="hidden" name="userId"  value="#url.userId#" />  
 <div class="formElement">  
 <label for="firstName">First Name</label>  
 <cfinput id="firstName" name="firstName"  value="#user.firstName#" />  
 <div id="firstNameError" class="error"></div>  
 </div>  
 <div class="formElement">  
 <label for="lastName">Last Name</label>  
 <cfinput id="lastName" name="lastName" value="#user.lastName#" />  
 <div id="lastNameError" class="error"></div>  
 </div>  
 <div class="formElement">  
 <label for="emailAddress">Email Address</label>  
 <cfinput id="emailAddress" name="emailAddress" value="#user.emailAddress#"  />  
 <div id="emailAddressError" class="error"></div>  
 </div>  
 <div class="formElement">  
 <label for="phone">Phone</label>  
 <cfinput id="phone" name="phone"  value="#user.phone#"  />  
 <div id="phoneError" class="error"></div>  
 </div>  
 <div><cfinput name="submit" type="button" value="Save User" onclick="submitForm()"><cfinput type="button" name="cancel" value="Cancel" onclick="ColdFusion.Window.hide('userWin')"></div>  
</cfform>

There's nothing terribly complex going on here.

First, we use <cfparam> to initialize the URL variable to an empty string. In the line that follows, we create an instance of the UserService object and call the getUser method, passing in the URL variable named userId.

The rest of the code simply populates the form with the information retrieved from the database. If this is a new user, the result retrieved from the database will contain empty strings, so our form will be empty.

One other point that's worth mentioning is how the Submit and Cancel buttons operate. The Submit button calls a JavaScript function named submitForm, while the Cancel button simply calls ColdFusion.Window.hide("userWin"), which hides the <cfwindow>. Under each form field, there's an empty div with an id similar to "{formFieldName}Error". This id will be used to display any error messages that are returned when the form is validated.

The final point worth making about this page is that it contains no JavaScript. Since this form will exist within our main page, we can store all of our JavaScript references there.

Processing the Form

Let's take a look at the submitForm function in index.cfm:

function submitForm() {  
clearErrors();  
ColdFusion.Ajax.submitForm("userForm", "userForm_submit.cfm", submitCallback, errorHandler);  
   }

The first task performed by the function above is to call the clearErrors methods, which clears any form validation errors that may exist in our form from previous usage. The second line of the code above performs the post -- the ColdFusion.Ajax.submitForm method takes the values of all of the items in the form named userForm, and posts them to the URL userForm_Submit.cfm. When the server sends back a response, the submitCallback function is called, and should there be any errors, the errorHandler method is executed.

Next let's take a look at the userForm_submit.cfm file. This is the file that we use to validate our form and save our user details:

<cfsetting enablecfoutputonly="true" />  
<cfset errors = StructNew() />  
 
<cfif form.firstName EQ "">  
 <cfset errors["firstName"] = "You must enter a first name." />  
</cfif>  
 
<cfif form.lastName EQ "">  
 <cfset errors["lastName"] = "You must enter a last name." />  
</cfif>  
 
<cfif NOT isValid("email", form.emailAddress)>  
 <cfset errors["emailAddress"]= "You must enter a valid email address" />  
</cfif>  
 
<cfif NOT isValid("telephone",form.phone)>  
 <cfset errors["phone"] = "You must enter a valid phone number" />  
</cfif>  
 
<cfif structIsEmpty(errors)>  
 <cfset createObject("component","com.user.UserService").saveUser(argumentCollection = form) />  
<cfelse>  
 <cfoutput><cfoutput>#serializeJSON(errors)#</cfoutput></cfoutput>  
</cfif>  
<cfsetting enablecfoutputonly="false" />

In this page, we've created a variable named errors that will hold any information relating to failed validation. The validation we're applying in this example is quite simple -- it checks to make sure that firstName and lastName are not empty strings, and that emailAddress and phone contain a valid email address and telephone number, respectively.

Once our data has been validated (assuming that our errors variable is empty), we can safely save it to our database. Once again, we create an instance of our UserService and call the save method, passing in the form scope as the argumentCollection. Our save method contains logic to determine whether we're dealing with a new user (that needs to be inserted) or an existing user (that needs to be updated).

If our errors variable is not empty, it means that our data contains errors. We need to pass them along in a way that will indicate to the main page that we encountered problems. This is best accomplished using JSON (JavaScript Object Notation), and fortunately, ColdFusion 8 has a native function, serializeJSON, to serialize a ColdFusion object into a JSON string.

By wrapping this call to this function in <cfoutput> tags, we're returning a serialized string that represents our error variable. There also exists a ColdFusion function named deserializeJSON that accepts a JSON string and returns a comparable ColdFusion data structure.

To see how we use the results from this page, let's revisit index.cfm and look at the code in our submitCallback method:

function submitCallback(response){  
     var errors = ColdFusion.JSON.decode(response);  
     var valid = true;  
       
     for(i in errors){  
   document.getElementById(i+"Error").innerHTML = errors[i];  
   valid = false;  
     }  
 if(valid){  
   ColdFusion.Window.hide("userWin");  
       ColdFusion.Grid.refresh("userGrid", true);  
 }  
       
   }

As you can see, the submitCallback function takes one argument, which is the response that was returned from the server when the form was submitted. Our first task is to decode the JSON string that's returned using ColdFusion.JSON.decode -- this will take the JSON string and turn it into a JavaScript object. As you may have suspected, there also exists a function named ColdFusion.JSON.encode that accepts a JavaScript object, and returns a JSON string.

If there are any errors in the errors JavaScript object, we loop over the elements in the object and set the innerHTML of the corresponding div for the form field. (These are the same divs that are cleared when the clearErrors method is called.) If any errors are returned, we set the variable valid to false.

If there are no errors returned, and the form is valid, we can happily close the <cfwindow> with the method ColdFusion.Window.hide("show"). Finally, we refresh the grid using ColdFusion.Grid.refresh so that any changes that were made will be reflected in the grid.

The only thing we haven't covered yet is how we display the form to create a new user.

Creating a New User

Our users can create a new user by clicking the New User button. This button calls the newUser JavaScript function:

function newUser(){  
 var url = "userForm.cfm" ;  
 ColdFusion.navigate(url, "userWin");      
 ColdFusion.Window.show("userWin");  
}

As you can see from the code above, this function is similar to the showUserForm function, with one exception -- we're not passing a userId in the URL. This approach will ensure that the <cfwindow> displays an empty form when it's opened.

You may have noticed the minimal amount of JavaScript in our code; if you look at the source code, you'll see a lot more. Whenever you use any of the ColdFusion Ajax components, ColdFusion will automatically pull in the JavaScript that's necessary for your component to function.

Summary

It may seem like there was a lot involved in this example, but given what we've accomplished -- a cross-browser compatible, rich interface for viewing and managing a list of users -- there really wasn't that much to it. Remember that our grid contains sortable columns and pagination, and we're making Ajax calls to refresh the grid as well as to display and process our form.

All of this was achieved with four relatively small ColdFusion files and about 30 lines of JavaScript. I think that speaks volumes about ColdFusion's capabilities for helping you create RIAs without getting bogged down in all the intricacies of JavaScript, Ajax, and browser compatibility issues.

This example merely scratches the surface of ColdFusion's Ajax capabilities. For more information on creating Ajax applications with ColdFusion 8, check out the ColdFusion Developer's Guide.

If you liked this article, share the love:
Print-Friendly Version Suggest an Article

Sponsored Links

Rate This Article

  • 1
    Poor
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
    Great

Comment on This Article

Have something to say?

Post A Comment

You need to be a member of the SitePoint Forums to comment on this post. Sign Up

Already a member? Post using your SitePoint Forums account: