HomeAbout Mark van HedelContact Mark van Hedel



Using FLEX for input forms in BlogCFC :: Part 5

Now that we seem to have everything working the way it should we can continue to the next part, this next part is submitting the data to the server and do all server related actions needed to post the comment and notify everyone that needs to be notified of this update. Of course for this we have to change the CFC on the server again and make a call to get this all done.

Since we do want to know again when a response from the server comes back we are going to create yet another responder to handle the result. This responder is again having 2 different methods to handle events from the server, the fault method one for throwing an alert message, and a result method to handle a correct save to the server. For this result method we are not doing anything but just close the window. To do this we make yet another call to Javascript to make Javascript refresh the parent screen and close the window.

package org.flexpair.blog.responders
{
   import flash.external.ExternalInterface;
   
   import mx.controls.Alert;
   import mx.rpc.IResponder;
   import mx.rpc.events.FaultEvent;
   import mx.rpc.events.ResultEvent;

   public class SubmitResponder implements IResponder
   {
      /**
       * Handle the result of retrieving entry data from the server
       */
      public function result(data:Object):void
      {
         // Fill the object with values
         var re:ResultEvent = data as ResultEvent;
         ExternalInterface.call("closeWindow");
      }

      /**
       * Handle any fault in the retrieval of entry data
       */
      public function fault(info:Object):void
      {
         //TODO: implement function
         var fault:FaultEvent = info as FaultEvent;
         Alert.show(fault.message.toString());
      }
      
   }
}

Now that this is implemented we are going to look at the CFC and add our submit method there. What I did for that is just copy part of the code from the normal addComment.cfm file and use that in my CFC.

<cffunction name="addComments" displayname="addComments" hint="Add comments to an entry" access="remote" output="false" returntype="void">
      <cfargument name="entryID" type="UUID" required="true">
      <cfargument name="commenterName" type="String" required="true">
      <cfargument name="email" type="string" required="true">
      <cfargument name="website" type="string" required="true">
      <cfargument name="comments" type="string" required="true">
      <cfargument name="subscribe" type="boolean" required="true">
      
      <cfset var rb = application.utils.getResource>

      <cfset var entry = retrieveEntry(arguments.entryID)>
      <cfset var commentID = application.blog.addComment(arguments.entryID,left(arguments.commenterName,50), left(arguments.email,50), left(arguments.website,255), arguments.comments, arguments.subscribe)>
      <cfset var subject = rb("commentaddedtoblog") & ": " & application.blog.getProperty("blogTitle") & " / " & rb("entry") & ": " & entry.title>
      <cfset var commentTime = dateAdd("h", application.blog.getProperty("offset"), now())>
      <cfsavecontent variable="email">
      <cfoutput>
#rb("commentaddedtoblogentry")#:   #entry.title#
#rb("commentadded")#:       #application.localeUtils.dateLocaleFormat(commentTime)# / #application.localeUtils.timeLocaleFormat(commentTime)#
#rb("commentmadeby")#:       #arguments.commenterName# <cfif len(arguments.website)>(#arguments.website#)</cfif>
#rb("ipofposter")#:         #cgi.REMOTE_ADDR#
URL: #application.blog.makeLink(arguments.entryID)###c#commentID#

   
#arguments.comments#
   
------------------------------------------------------------
#rb("unsubscribe")#: %unsubscribe%
This blog powered by BlogCFC #application.blog.getVersion()#
Created by Raymond Camden (ray@camdenfamily.com)
         </cfoutput>
         </cfsavecontent>
   
         <cfif not application.commentmoderation>
            <cfset application.blog.notifyEntry(entry.id, trim(email), subject, arguments.email)>
         <cfelse>
            <cfset application.blog.notifyEntry(entry.id, trim(email), subject, arguments.email, true)>
         </cfif>
      <cfmodule template="../../../tags/scopecache.cfm" scope="application" clearall="true">
   </cffunction>

I've just given all properties to this method that were needed and in the method I do retrieve the resource bundle again since it's not known in the cfc if I don't. I would usually never call an application scoped variable directly inside a CFC but for now I've just done this since this is the easiest way. Now I can submit the post to the database, after that send notification emails and finally clear the cache so it will also show this new entry to screen. So as you might see all the steps that were also done in addComment.cfm.

Now the final part is to make the call to this method and our form will be fully functional.

/**
* Handle the submission of the form to the server
*/
private function saveComments():void {
   var submitResponder:SubmitResponder = new SubmitResponder();
   var token:AsyncToken = remoteUpdate.addComments(_entry.id, _comments.name, _comments.email, _comments.website, _comments.comments, _comments.subscribe);
   token.addResponder(submitResponder);
}

Now there is one more part that is not working yet, and that is the saving of user values to the users machine. Since the form was completely build in ColdFusion it would make sense to do that with cookies, but since we now changed to using FLEX we can use Local Shared Objects for storing the information to the users machine. So for that we create a new SharedObject at the top of our CommentsAs.as file and retrieve a shared object from the client.

// Shared object to hold user data on the users machine
private var _so:SharedObject = SharedObject.getLocal("BlogData");
I've named this SharedObject BlogData on the users machine, it doesn't matter what name you want to give it, it's just like the name of the cookie, so if you use another name from the start it will not be a problem.

Now we can create a method to save the user information to this Shared Object, to do this we just add variables to the data property of the Shared Object.

/**
* since this is a flash form and not html anymore we can save the user information to a shared object on the users machine
* instead of saving it to cookies.
*/
private function saveUserValues():void {
   if (_comments.remember){
      _so.data.commenterName = _comments.name;
      _so.data.email = _comments.email;
      _so.data.website = _comments.website;
      // immediately store data to disk
      _so.flush();
   } else {
    _so.clear();
    _so.flush();
   }
}
With saving these values we do a flush after setting the values to save the data directly to the users machine, if we don't flush it it will be saved a little later, but we better be sure it's saved.

Now that this is done we can go back to one of our initial methods to retrieve data and change the way we retrieve data there. This since we want to watch for this shared object and not retrieve everything from cookies. So for that we will first check if our Shared Object is filled, if it is, we will retrieve the data from there, if it's not we will retrieve it from cookies, and if that's empty we'll just leave the fields blank.

/**
* Fill with default values if a user has decided to remember it's settings.
*/
private function fillComments():void {
   if (_so.data.commenterName != undefined) {
      commenterName.text = _so.data.commenterName;
      email.text = _so.data.email;
      website.text = _so.data.website;
   }else {
      commenterName.text = ExternalInterface.call("getName");
      email.text = ExternalInterface.call("getEmail")
      website.text = ExternalInterface.call("getWebsite");
   }
   if (commenterName.text.length >= 2 || email.text.length >= 5 || website.text.length >= 10){
      remember.selected = true;
   }
}

It seems now our application is fully functional. I'll just add one more post of information at the end and add all the files there that I used to create this. And some information about how all this is done and what to do to replace the current form in BlogCFC.

Comments
BlogCFC was created by Raymond Camden. This blog is running version 5.9.002. Contact Blog Owner