Validating "Pages" in CFFORM (2)

Here is a new version of the checkFieldSet UDF. Brett found a few issues in my UDF. First - I accidently left in a hard coded form name, donations. This was from the project I was working on. Secondly, I thought there was no way to get the particular error message for a field. Brett showed that you could get it simply by using #f#.errorString, where f is the field name. He also showed that if you put 'Error' in your second argument in the alert call it marks it as an Error window.

So - I took his code mod and modded it some more. Now the error message isn't an optional argument - it is the combination of all the error messages in the current field set. (By that I simply mean the page, or tab/accordion.)

So - here is the latest version. Enjoy.

<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.">
            
   <cfset var vcode = "">
   <cfset var f = "">
               
   <cfsavecontent variable="vcode">
      var ok = true;
      var msg = "";
      <cfloop index="f" list="#arguments.fields#">
         <cfoutput>
         if(!mx.validators.Validator.isValid(this, '#arguments.form#.#f#')) { msg = msg + #f#.errorString + '\n'; ok=false; }
         </cfoutput>
      </cfloop>
   </cfsavecontent>
   <cfset vcode = vcode & "if(!ok) mx.controls.Alert.show(msg,'Error'); ">
   <cfset vcode = vcode & "if(ok) #ascode#">   
   <cfset vcode = replaceList(vcode,"#chr(10)#,#chr(13)#,#chr(9)#",",,")>
   
   <cfreturn vcode>      
</cffunction>

Archived Comments

Comment 1 by Brett Liotta posted on 2/12/2005 at 12:41 PM

Your welcome Ray. Thank you for this UDF validation concept. By the way, your credentials are very impressive. I'm going to try to attend your Macrochat coming up in a few days.

I realized that our projects are a bit different so I had to mod the function a little bit more to work for my purposes. Here are the differences in our projects.

Yours is a flash form with multiple accordion tabs. Each accordion tab is a separate step and you can only move forward in the tabs if each tab passes form validation.

Now here's mine: you can move around in the tabs at any point (not separate steps) in the data entry process. The fields on each tab are submitted as one step when all tabs pass form validation rules. This is a bit more complicated and I'm still working out a solution. I also have some fields that are required only when some other field has been filled out (dynamic validation). It's a pretty complicated Data Entry process. I really like the whole flash concept, but yeah I do see a bit of a learning curve with ActionScript. I guess it was just a matter of time that I was going to have to learn it. What better time than this?

Or, I can always go back to regular forms or XML forms..

Any thoughts? Kind of an open forum post, than a specific problem.

The more I think about it, the more I'm thinking it might be easier to just do it the step way like you.

Comment 2 by Steve Moore posted on 2/15/2005 at 1:30 AM

Seems like the programmatic interface to these Flash forms comes from the Flex environment. Without knowing Flex, is there documentation on this stuff somewhere?

Comment 3 by Raymond Camden posted on 2/15/2005 at 1:34 AM

If you go to LiveDocs, go into Flex, then... into the AS portion and you will be in the right area.

Comment 4 by johnb posted on 2/16/2005 at 3:48 PM

if i could just figure out how to move between the tabs from clickig buttons...I'm no AS guy! YET!

Comment 5 by Raymond Camden posted on 2/16/2005 at 7:57 PM

It is very easy. For accordians, you can add this to the onClick to the button:

accordion1.selectedIndex=2

It should be simular for tabs. Note, "accordian1" is the name value for the accordion.

Comment 6 by johnb posted on 2/16/2005 at 8:04 PM

thanks Ray - looking forward to tonights session!

Comment 7 by johnb posted on 2/16/2005 at 11:22 PM

FYI - just seen this too, http://www.macromedia.com/c... which points to using the ID attribute over the name for selected components.

Comment 8 by Raymond Camden posted on 2/17/2005 at 2:39 AM

Hmm, ok. I'll use ID next time. Name seemed to work fine for me.

Comment 9 by pim posted on 2/25/2005 at 11:40 PM

the onClick stuff to select an index in the accordion is nice, I have tried to find a way to do this when the form is initialized, but there is no onLoad event on any form component, nor in the cfform itself, do you have an idea how to perform this???

Comment 10 by Brett Liotta posted on 2/26/2005 at 1:14 AM

pim, its pretty easy. all you have to do is add the attribute [selectedIndex="thetabnum"] to your cfformgroup tag. see following code:

&lt;cfform type="flash"...&gt;
&lt;cfformgroup type="tabnavigator" selectedIndex="#url.tab#"&gt;
&lt;cfformgroup type="page" label="General"&gt;
some cfinputs..
&lt;/cfformgroup&gt;
&lt;cfformgroup type="page" label="Special Instructions"&gt;
some cfinputs..
&lt;/cfformgroup&gt;
&lt;/cfformgroup&gt;
&lt;/cfform&gt;

so whats going to happen here is say the variable url.tab is a 1. the flash form will open with the second tab selected (viewable). Keep in mind almost everything in flash is based on 0 now being the first in an array (b/c of actionscript). so [selectedIndex="0"] will be referencing the first tab and 1 will be referencing the second tab, etc.

Comment 11 by Brett Liotta posted on 2/26/2005 at 1:15 AM

Ray, how do I post code sample so it doesn't look like junk?

Comment 12 by cfm_pedawan posted on 3/2/2006 at 4:03 AM

Hi all.

I am sure this is a silly question.

I have created a 6 page multi-step CFFORM and I want to validate one of the tabs to ensure a users answser at least one question. Unfortunatly the spec will not let me use a required say text field that will take a Y or N value.

So I searched the net and found this partial solution.

But how do you use this UDF with flash forms. Does it have to within the tab/page being validated to be called? I currently have it above my <cfform> and I am not getting the alert messages.

Here is my code for the executing button on the tab I am validating.
<!--- Push To Next Tab --->
<cfinput value="Continue..." onClick="tnav.selectedIndex=5;" type="button" name="tab5_btn" width="100">

Any help is appreciated.

Thanks..

Comment 13 by Raymond Camden posted on 3/2/2006 at 4:06 AM

THe UDF simply returns the AS code needed to check the page. So you put the call in the button that leads from one page to another.

Comment 14 by Raymond Camden posted on 3/2/2006 at 4:07 AM

The previous post may help:

http://ray.camdenfamily.com...
entry&entry=F002F1C6-C060-F0E5-EB698A2C0202209D

Comment 15 by cfm_pedawan posted on 3/2/2006 at 4:08 AM

...Drat!! wrong sample code. Here is the correct code

<!--- Push To Next Tab --->
<cfinput value="Continue..." onClick="#checkFieldSet("field1,field2","formname","tnav.selectedIndex=4")#" type="button" name= "tab4_btn" width="100">

Thanks...

Comment 16 by cfm_pedawan posted on 3/2/2006 at 6:07 AM

Below is an example of the code I have...I chopped up the original code so I could post this watered down version. I am don't know what I am doing wrong.

- The function is included
- I am calling the function in my the tab that I need the field validated?
- ???

Any Thoughts? Any is appreciated...

<code>
<!--- Begin Tab Field Check Function --->
<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.">

<cfset var vcode = "">
<cfset var f = "">

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

<cfreturn vcode>
</cffunction>
<!--- End Tab Field Function --->

<!--- Begin CFFORM --->
<cfform format="flash" width="550" height="400" timeout="1000" skin="haloblue" name="demotab">

<cfformgroup type="panel" label="Multi Step Form" width="400" height="300" style="marginRight:2; font-size:12px; color:##000000; headerColors:##FFFFFF; dropShadow:0; headerHeight:22; panelBorderStyle:'roundCorners'; backgroundColor:##FFFFFF">

<!--- Begin Tab Navigation Box --->
<cfformgroup type="tabnavigator" id="tnav" name="tnav">

<!--- Begin Tab 1 --->
<cfformgroup type="page" label="Tab1" width="650" height="300">

<!--- Headers --->
<cfformitem type="html">
<font size="-1" color="##666666">
<br>
<b>Contact Info:</b><br>
</font>
</cfformitem>

<!--- Form Fields --->
<cfinput type="text" name="contName" label="Name:" size="20" value="" required="yes" message="Please Enter Contact First Name">
<cfinput type="text" name="contEmail" label="Email:" size="20" value="" required="yes" message="Please Enter Valid Contact Email Address" validate="email">
<cfinput type="text" name="contPhone" label="Phone:" size="20" value="">

<!--- Push To Next Tab --->
<cfinput value="Continue..." onClick="tnav.selectedIndex=1;" type="button" name="tab1_btn" width="100">

</cfformgroup>
<!--- End Tab 1 --->

<!--- Begin Tab 2 --->
<cfformgroup type="page" label="Tab2" width="400" height="300">

<!--- Header --->
<cfformitem type="html">
<font size="-1" color="##666666">
<br><b>Select Geography: (Select all that apply)</b>
</font>
</cfformitem>

<!--- Form Fields --->
<cfformgroup type="tile">
<cfinput type="checkbox" name="Amer1" label="North America">
<cfinput type="checkbox" name="Amer2" label="South America">
</cfformgroup>
<cfinput type="text" name="Other" label="Other:" size="10">

<!--- Push To Next Tab --->
<cfinput type="button" name= "tab2_btn" value="Val_This_Tab" onClick="#checkFieldSet("Amer1,Amer2,Other","demotab","tnav.selectedIndex=2")#" width="100">

</cfformgroup>
<!--- End Tab 2 --->

<!--- Begin Finish Tab --->
<cfformgroup type="page" label="Finish" width="400" height="300">

<!--- Header --->
<cfformitem type="html">
<font size="-1" color="##666666">
<br>
<b>Comments:</b><br>
</font>
</cfformitem>
<!--- TextArea field --->
<cftextarea name="Comments" wrap="virtual" rows="5" cols="30" validate="maxlength" validateAt="onBlur" maxlength="500">
</cftextarea>

<!--- Submit Request --->
<cfinput type="submit" name="submit" value="Submit Request">

</cfformgroup>
<!--- End Finish Tab --->

</cfformgroup>
<!--- Begin Tab Navigation Box --->

</cfformgroup>

</cfform>
<!--- End CFFORM --->
</code>

Comment 17 by cfm_pedawan posted on 3/10/2006 at 6:43 AM

Hi all,

Could someone post some example code of how you got the UDF to work? Please post UDF + CFFORMS... I am looking over my code and I can't seem to figure out why the alerts are not popping up etc when no field is select on X tab. I have posted my code in the post above. Any help would be much appreciated.

</thanks>

P.S
I am really weak with all the AS stuff, need to catch up "FLEX TIME"

Comment 18 by Rod Kesselring posted on 11/27/2006 at 9:35 PM

Ok i have run into a bit of an issue... I am working with tab navigator and using a button to step to the next tab... but when i check the values of the fields the function fies and the boxes turn red but i get no alerts and the whole form seems to become disabled. I cannot place the cursor in any text field or type anything else into the form. If I submit the entire form I get the same issue. Have you seen anything like this? Am i doing something wrong? I will be glad to send you the code but i don't want to fill up the blog with a lot of extraneous code if not needed.

Comment 19 by Rod Kesselring posted on 11/27/2006 at 9:37 PM

the function "fires" sorry for the typo