Ask a Jedi: Mixing cfform validation and ajax-based functions

This post is more than 2 years old.

Andy asks:

If you have an ajax/html form and you submit using a button control which calls a function (like ColdFusion.Ajax.submitForm) is there still a way to easily take advantage of the built in cfform validation? This usually gets called when you use a submit, rather than a button, and I'd love to be able to call it right before I call my function that handles the cfform submission.

If I read you right - you want to know if you can use cfform validation as well as using your own logic after the validation. If so, it works pretty easily:

<cfif not structIsEmpty(form)> <cfdump var="#form#" label="Form"> </cfif>

<script> function doSomething() { alert('Called'); return false; } </script>

<cfform name="test" onSubmit="return doSomething()"> Who is the twelfth cylon? <cfinput name="name" required="true"> <cfinput name="submit" type="submit" value="Submit"> </cfform>

So read this from the bottom up. I've got a super simple form using CFFORM's built in validation for a grand total of one field (I'm easy like Sunday morning). Note the onSubmit. What's cool, and what I wasn't sure would work, is that doSomething won't run if there are any errors. As soon as your form is ok, it runs.

I'm very much a anti-cfform kind of guy, so I may be missing something obvious, but I hope this answers your question.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Devon posted on 1/12/2008 at 4:58 AM

I posted on using cfform and Spry validation a while back. In fact it's one of the few things I've actually posted on. I hopefully finish my BSc in a week and then I'll start posting more...well that's the plan.

<a href="http://blog.fusefly.info/in..." > Using CFFORM and Spry validation </a>

Comment 2 by Scott P posted on 1/12/2008 at 7:37 AM

The twelfth cylon is me - I have been waiting to tell you until the time was right.

Comment 3 by dickbob posted on 1/12/2008 at 8:50 PM

"As soon as your form is ok, it runs." hummm, I see that as a deal-breaker. So it's no good for extending form validation. Like seeing if one date is before another.

I must say I've been disappointed with the new UI functions in CF8.

Several things don't seem to work inside a cflayoutarea...

1. cfform with a enctype="multipart/form-data"

2. Two submit buttons with differing values

3. Spry accordions

Maybe I'm pushing CF too far on the client-side with my UI demands? Maybe I should remember CF is a server-side technology and pick up a book on Flex to get my demanding client-side stuff done?

It seems to offer so much (cfinput type="datefield") but drops the ball when you try and hang several features together.

Comment 4 by Raymond Camden posted on 1/12/2008 at 9:00 PM

@dickbob: Um, maybe I don't get your complaint. You can run code after CF does it's stuff and check for other items, like your date example. YOu can then do an alert and return false.

This post has nothing to do with CF8 and UI controls so I'm not sure why you bring that up here. But let me address your concerns:

1) cfform with a enctype="multipart/form-data"

Yep, you can't do file uploads via an ajax http hit. That's a browser limitation, not CF.

2) "Two submit buttons with differing values"

I've never seen issue with multiple submit buttons. But in theory all you have to do is use onClick on a button. Do X if you hit button 1, and Y if you hit button 2.

3) "Spry accordions"

Well, that may be Spry's fault too.

I think Adobe did a good job with the Ajax stuff. Yes, it will not cover every situation. That would be impossible, but they do provide good stuff out of the box.

Comment 5 by dickbob posted on 1/12/2008 at 9:17 PM

@Ray: Sorry the complaint is that with form validation I want all the invalid fields to be alerted at once. Not half when the cffform validation is run and then another alert when that's okay but when my handcoded validation kicks in. Maybe I'm being unreasonable. Obviously the onSubmit function might not be field validation at all but some other action in which case my requirement might not suit someone else. :-)

Yes you're right I am a bit OT with my UI rant. Just had a frustrating week trying to get CF to do want I want :-)

1) Okay, I didn't realise that was a browser/ajax issue - sorry CF

2) I didn't want to have to code around what seems to be an necessary limitation. In a regular HTML form two submit button with the same name will return the differing values depending on which is clicked.

3) In my test it was so close. The CSS was laying out the panels and title bars but the JS wasn't closing up the panels and the bars weren't reacting to any clicks.

Maybe I should rip the whole lot out of CF and do it all directly in Spry? Which is, of course, what is behind most of this functionality.

Comment 6 by Raymond Camden posted on 1/12/2008 at 9:33 PM

2) Can you define your issue more? I've never seen an issue with 2 submit buttons. What is the problem you are having? I ran this code:

<cfform name="f" method="post">
<cfinput type="submit" name="alpha" value="alpha">
<cfinput type="submit" name="beta" value="beta">
</cfform>

<cfdump var="#form#">

And it worked perfectly. If I click beta, I see beta, and vice versa.

Going back to your original issue, it would be nice if you could say, "Hey CF, run YOUR tests, return the results, then let me do my tests, and I'll show one error". Flex allows for that. CF does it's best though. Don't forget you have other options as well. You can write your own validation routines as well. So you could have 2 fields for dates that are required, and write custom validation for them. If your intent is "dates must be filled" and "date a must be before date b", then you have to cover both of that - but the point is - you can customize stuff up a bit. And the rest of your form can use 'normal' cf validation. So you don't have to throw away the whole thing.

"Maybe I should rip the whole lot out of CF and do it all directly in Spry? Which is, of course, what is behind most of this functionality. "

Are you saying Spry is behind CF8's Ajax stuff? If so - you are wrong. It is mostly Ext and Yahoo stuff, although there is some Spry stuff. As for ripping out CF and doing all Spry, you would be the best judge of that for sure.

Comment 7 by dickbob posted on 1/13/2008 at 12:15 AM

2) Sure, try this...

<cflayout name="test" type="tab">
<cflayoutarea name="tab1" title="Tab 1">
<cfform name="f" method="post">
<cfinput type="submit" name="alpha" value="alpha">
<cfinput type="submit" name="beta" value="beta">
</cfform>
</cflayoutarea>
</cflayout>

What do you get? I get alpha even if I click beta.

"You can write your own validation routines as well". Are you talking about using onValidate? Your reply got me to lookup the attributes of cfinput again. This could be a good approach. Obviously it drops the benefit of the validate attribute but I guess I could clone the code into my function and then extend it. Fair point.

By "what is behind most of this functionality" I was inferring the the tabs/panels stuff of cflayout rather than the form validation of cfform.

I appreciate your time and thoughts at the weekend :-)

Comment 8 by Raymond Camden posted on 1/13/2008 at 1:32 AM

Yep, looks to be a bug. Make sure you log it at www.adobe.com/go/wish

Just to be picky - if you use onValidate, you lose built in validation for _that_ field, so using your example of a form and needing to check 2 dates, if you had N fields, you can use the built in stuff for the rest at least. :)

Comment 9 by mahcsig posted on 1/13/2008 at 3:19 AM

I only have CF7 installed here, but you could include /cfide/scripts/cfform.js and use the CF javascript functions:

_CF_checkdate
_CF_checkinteger
_CF_checkphone
_CF_checkzip
etc...

Comment 10 by dickbob posted on 1/15/2008 at 1:34 PM

@Ray: Bug logged

@mahcsig: That JS script is also included when CF8 builds a CFFORM

Comment 11 by Doug - C4S posted on 6/19/2008 at 7:05 PM

dickbob:
In regards to this bug:

"I ran this code:

<cfform name="f" method="post">
<cfinput type="submit" name="alpha" value="alpha">
<cfinput type="submit" name="beta" value="beta">
</cfform>

<cfdump var="#form#">

And it worked perfectly. If I click beta, I see beta, and vice versa."

Did you ever find a solution around it or get a bug resolution? I am tearing my hair out over this one!

Comment 12 by dickbob posted on 6/19/2008 at 11:26 PM

@Doug: Sorry, no solutions and I've not tried it since.

I've decided ColdFusion doesn't do client-side.

After playing with cfform etc in earlier versions and the Ajax stuff in CF8 I've concluded there are too many compromises. Sure, it gets you up and running quickly and if your UI requirements are simple then it's a quick win but anything really creative or demanding then you'll soon hit a brick wall.

Use CF for what it was originally designed for: Server-side business logic and data interaction. Leave the glitzy client-side stuff to jQuery/EXT/YUI/Spry etc or better still invest some time in Flex as I am.

Let's hope the CF9 development team don't waste too much time on building client-side functions for the Marketing department :-)

Comment 13 by Doug - C4S posted on 6/19/2008 at 11:33 PM

You KNOW Adobe will invest the majority of efforts in the UI though... After all, it is sold as a RAD type product.
I have mixed feelings, I like the "ease" of many of the functions, just not the shortcomings. (Hmmm... my dad's voice in my head - "nothing worthwhile is ever easy". BUT is the inverse ALMOST true in this case? "nothing easy is worthwhile")HA!
Wish I had more time to invest in Flex. I'll get there. I'm still converting a client from old 3.0 written code.

Comment 14 by Greg Thompson posted on 12/30/2008 at 10:47 PM

Try this code to have multiple forms in cflayout

<cflayout name="test" type="tab">
<cflayoutarea name="tab1" title="Tab 1">
<cfform name="f1" method="post">
<cfinput type="text" name="hello" value="">
<cfinput type="button" name="alpha" value="alpha" onClick="this.form.submit()">
</cfform>
</cflayoutarea>
<cflayoutarea name="tab2" title="Tab 2">
<cfform name="f2" method="post">
<cfinput type="text" name="helloworld" value="">
<cfinput type="button" name="beta" value="beta" onClick="this.form.submit()">
</cfform>
</cflayoutarea>
</cflayout>
<cfdump var="#FORM#">

Comment 15 by wembly posted on 4/8/2011 at 5:55 AM

been a while since thread was active, for those of us still playing around with this. I don't know if it is better in cf9, but the 'hack' i found you can use in the cfform tag is to do something like this...

<cfform name="myForm" method="post" action="post.cfm" onSubmit="myAjaxFunction();return false;">

Not the most graceful logic, but the return false at the end of the onSubmit will override the return true CF is nice enough to put in there by default.

Comment 16 by Jack posted on 2/2/2015 at 2:11 AM

Hi Raymond, I know this is old post. What I am trying to do is very similar

http://stackoverflow.com/qu...

but I can't seems to make it work. I also tried putting the onsubmit in the cfform tag but it won't work because my signin function is actually a CF template and not a script. If the signin is not successful it will loop within the popup. If it is successful it will call window.document.forms[0].submit(); to submit the form

Any help is appreciated. Thank you.

Comment 17 (In reply to #16) by Raymond Camden posted on 2/2/2015 at 3:45 AM

I honestly can't recommend anything more than removing cfform. You say your signin function is actually a CF template. I'd start by changing it so that it can accept username/password values sent by Ajax and just return a 0 or 1 to represent a valid set of credentials.

Comment 18 (In reply to #17) by Jack posted on 2/2/2015 at 10:39 PM

Hi Raymond, I am not familiar with Ajax. I am open to all solutions. If you can give me an example, that will be greatly appreciated.

Comment 19 (In reply to #18) by Raymond Camden posted on 2/2/2015 at 10:42 PM

An example of Ajax? That's pretty broad. :) You could maybe start w/ my video series on jQuery: https://www.youtube.com/pla...

Comment 20 (In reply to #19) by Jack posted on 2/2/2015 at 10:44 PM

An example of how you would code in my case :)

Comment 21 (In reply to #20) by Raymond Camden posted on 2/3/2015 at 12:25 AM

Sorry - no.