So, I'm working on a CFFORM application now to process donation requests. This used to be a 5 step process over a bunch of JSP files. It is now being rewritten for ColdFusion MX 7. I set up the form to use the accordion style. After some initial hurdles (see my others posts), I had something I was proud to show off. Instead of 5 different pages, I now had one simple (and pretty) Flash based form.

Then my boss checked it out and asked why he could go from one accordion to another when the fields weren't correct. I pointed out that the validation would fire at the end of the process, but he said this wasn't very intuitive. I agreed - and began to deep. After talking with Nimer, he pointed me to the following piece of code:

onClick="mx.controls.Alert.show(mx.validators.Validator.isStructureValid(this,'form1'))"

This litte piece of code will fire the a function, isStructureValid, that will check the entire form. This was close - but not what I needed. I dug around the ActionScript documentation for Flex until I found: mx.validators.Validator.isValid(a,b). This will check one particular field to see if it is ok.

So - I know how to check particular fields. I could then add a Next button to my accordion page so that when you clicked on it, I checked the fields for that page. It wasn't automatic - but it worked.

My next step was to design a UDF to spit out the ActionScript code for me. With that in mind, I present checkFieldSet:

<cffunction name="checkFieldSet" output="false" returnType="string">
   <cfargument name="fields" type="string" required="true" hint="Fields to search">
   <cfargument name="form" type="string" required="true" hint="Name of the form">
   <cfargument name="ascode" type="string" required="true" hint="Code to fire if all is good.">
   <cfargument name="message" type="string" required="false"
            default="You have not completed one or more of the items on this page.\nPlease correct the items in red."
            hint="Message to display on error.">

            
   <cfset var vcode ="">
   <cfset var f ="">
               
   <cfsavecontent variable="vcode">
      var ok = true;
      <cfloop index="f" list="#arguments.fields#">
         <cfoutput>
         if(!mx.validators.Validator.isValid(this, 'donations.#f#')) { if(ok) mx.controls.Alert.show('#arguments.message#'); ok = false;};
         </cfoutput>
      </cfloop>
   </cfsavecontent>
   <cfset vcode = vcode &"if(ok) #ascode#">   
   <cfset vcode = replaceList(vcode,"#chr(10)#,#chr(13)#,#chr(9)#",",,")>
   
   <cfreturn vcode>      
</cffunction>

The UDF works pretty simply. You pass it the name of the fields you want to check. Then you tell it the name of the form. I'll be honest here - I'm not sure this is 100% required. More on that later though. Next, you pass in the ActionScript code you want to fire if all the fields pass their validation. Lastly - there is an optional argument that lets you specify the message to display. As you can see, this is a nice and vague message since we can't get the real message for each "bad" field. Actually, I prefer this message. When the isValid fires, it will mark the bad fields anyway, so the message simply tells the user what to look for.

Here is an example of how to use it:

<cfinput type="button" name="step3b" value="Next" onClick="#checkFieldSet("credicart,ccnumber,nameoncard,ccmonth,ccyear","donations","accordion1.selectedIndex=3")#">

So - the ActionScript. I'm sure I could have written it better. All I know is that it works. :) So feel free to suggest something a bit tighter.