August 15, 2005

somewhat less cheesy flash forms trick

everybody's doing it. you know you want to. so why not go ahead and get on the flash forms bandwagon? it seems like pretty much every cf developer on the block has now developed a penchant for using cf7's new flash forms. quite a large part of this popularity is due to the ActionScript injection gravy that's been posted on AS Fusion,cf_pim and cfform. who would have thought a few lines of ActionScript would have breathed that kind of life into something as bland as a form?

one of things that took some time for me to catch on to was that the AcstionScript we were injecting into our flash forms, wasn't quite "live". for example, what would the following alert show if injected into a form button that some cranked up monkey was taught to push once a minute for an hour?

<cfsavecontent variable="testInc">
var x=1;
x=x+1;
alert(x.toString());
</cfsavecontent>


while i suppose pretty much everyone else knew the correct answer (2), it took me almost an hour to figure that out. if you wanted to have that var updated you'd need to store it's values outside that snippet (which is re-run exactly as is whenever that crazy monkey mashed down it's button), the usual suspect being one flavor or other of cfinput. even in moderately complex apps this inevitably leads to a plethora of cfinputs named (in our naming scheme) like cheesyFolderHolder, cheesyServerStatus, cheesyIMAPserver, cheesyGrabBag, etc. the relationships and interactions between these can get kind of hairy for a cf developer more used to the seemingly cleaner environment of the back-end (well it seemed kind of by-the-seat-of-your-pants to me anyway).

luckily one of the more interesting bits of ActionScript that cfform does allow is sharedObject (you flash developers can avert your eyes while i try to explain this to my fellow cf developers, it's kind of like a cookie, ok you flash developers can look now). so you can do things like:

<cfsavecontent variable="startUp">
// Create a local shared object
var so = SharedObject.getLocal("imapClient");
so.data.username="joe@blow.com";
so.data.password="yup, still crazy";
so.data.host="blow.com";
so.data.port=143;
so.data.currentFolder="INBOX";
so.data.getHeaders=false;
so.data.debug=false;
// write it out to the client
so.flush();
}   
</cfsavecontent>


which makes the info contained in the data part of that "imapClient" sharedObject available to other ActionScript snippets:

<cfsavecontent variable="checkEmail">
var imapObj=SharedObject.getLocal("imapClient");
var mailArgs = {
   username:imapObj.data.username,
   password:imapObj.data.password,
   imapHost:imapObj.data.host,
   folder:imapObj.data.currentFolder,
   getHeaders:imapObj.data.getHeaders,
   debug:imapObj.data.debug,
   allMessages:true};
.
.
.
//get service
imapService = connection.getService("cfc.remoteIMAPFacade",responseHandler);
//make call
imapService.fetchProfile(mailArgs);   
</cfsavecontent>


one downside is that users can turn this functionality off like cookies in a browser, so you'd need to test for this and fallback accordingly (though i think this means the data won't be saved locally but still available between snippets).

thanks to seth duffy for suggesting this idea.

0 Comments:

Post a Comment

<< Home