Ask a Jedi: Trouble with ColdFusion.Ajax.SubmitForm

This post is more than 2 years old.

Andy asks:

This is probably a stupid question but I can't seem to get this to work. I'm using a ColdFusion.Ajax.submitForm and I thought that I would be able to return something from the form's submit handler page using my callback function. I can't seem to get this to work. I tried toa variable on the submit handler page to give it back to the caller page where the form lives but I just get a giant javascript dialog when I try to test this out using an alert in the callback function to display my callbackMsg. Should I be taking a different approach? I really need to get the primary key of the newly inserted record back and can't seem to return it to the calling page.

Now now, Andy, as we all know, there are no stupid questions, just stupid programming languages. That being said, I have a good idea of what you are running into.

Let's start with a super simple example. I'll build a form with two text fields. These fields will represents two numbers. A third field will be used for the answer. Finally I'll add a button:

<form id="myform"> <input type="text" name="number1"> + <input type="text" name="number2"> = <input type="text" id="result"> <input type="button" value="Solve" onclick="solve()"> </form>

Notice that the onclick runs solve. Let's look at that:

function solve() { console.log('running...'); ColdFusion.Ajax.submitForm('myform','test.cfm',resultHandler); console.log('done...'); }

First and foremost - look at my use of console.log. You need to stop using Alert. I know it's easy. But Alert can be a real pain in the you know what. Download Firebug and get used to doing your debugging there. Ok, so in between two debug statements I'm running a submitForm action. I've said to submit myform to test.cfm and then run resultHandler.

I made test.cfm simply cfoutput a random number for testing purposes.

The first thing I ran into was that ColdFusion.Ajax.submitForm didn't exist. Remember that ColdFusion only loads the Ajax functionality it thinks it needed. Since I didn't really use any ColdFusion tags, it didn't load squat. The trick to handle this was discovered by Todd Sharp, just add this to the top of your page:

<cfajaximport />

Ok, so now I can run my application and see the request, how do we handle it, and why is he getting a large alert? First look at a more full test.cfm:

<cfparam name="form.number1" default="0"> <cfparam name="form.number2" default="0">

<cfset form.number1 = val(form.number1)> <cfset form.number2 = val(form.number2)>

<cfoutput>#form.number1+form.number2#</cfoutput>

(And by the way, I should be more anal with my URL checks in this code.) Now let's look at resultHandler:

function resultHandler(result) { console.log('result handler ran...'); console.log(result); }

When I ran my test, I noticed that result was indeed a large string with a lot of white space. That could be what you are seeing in the large alert. The white space is simply a result of ColdFusion liking whitespace like a Lohan needs publicity.

We can fix this a few ways. We can reduce the whitespace in the CFM with a simple CFSETTING. But that's kinda boring. When I saw this on ColdFusionBloggers</a. a few minutes ago I thought it was perfect timing:

Cranky Bit: Trimming a String in JavaScript

I added his code (note his regex is missing a \ in front of each s) and ended up with this:

<script> String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g,""); }

function resultHandler(result) { console.log('result handler ran...'); console.log(result.trim()); }

function solve() { console.log('running...'); ColdFusion.Ajax.submitForm('myform','test.cfm',resultHandler); console.log('done...'); } </script>

Now when I ran the code I got a nicely trimmed response. I added one more line to set the result value:

document.getElementById("result").value = result.trim();
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 Rick Smith posted on 7/3/2008 at 8:55 PM

I can't say how hard I laughed at the link to "programming languages"

Comment 2 by Chris Schofield posted on 7/3/2008 at 9:39 PM

Great information, Ray! Thanks for asking Andy! And not to take away from the post itself, but ditto on Rick's comment. Classic!

Comment 3 by Andy Sandefer posted on 7/3/2008 at 9:58 PM

LOLOLOLOL
The PHP link made me chuckle but the Lohan reference was the real comedy here folks!

Thanks a bunch!
Andy

Comment 4 by Joshua Curtiss posted on 7/16/2008 at 2:04 AM

Thanks for the link to my post, Ray! The code view plugin for WordPress apparently gobbled up the backslashes in the trim function code and I overlooked that after posting it. It's fixed now. That's what I get for using a PHP-based blogging engine. ;-D

Comment 5 by Edward Beckett posted on 10/20/2008 at 3:38 AM

This is the exact problem I'm also having ... I have two CFSelects bound to functions in a CFC to populate the option values asynch. NP there ... However, I'm trying to submit the form to a CFWindow through ColdFusion.Ajax.submitForm and the results don't populate to the destination window.

Here's some code .... The originating form page ...

showIt = function() {
ColdFusion.Window.create("gotopage","Find a Location","gotopage.cfm",{center:true,modal:true,draggable:true,width:550,height:375})
}

submitForm = function() {
console.log('running...'); ColdFusion.Ajax.submitForm("stateLookUp","gotopage.cfm",showIt);
console.log('done...');
return false;
}

<cfform name="stateLookUp" id="stateLookUp" onSubmit="return submitForm()" method="post">
<div id="stateContainer" >
<div align="center"><h3 style="margin-right:150px;">Please Select a State</h3></div>
<cfselect name="state" id="state" bind="cfc:blog.com.bindFcns.getstates()" bindonload="true" value="#form.state#" >
<option name="0">State</option>
</cfselect>
<cfselect name="city" id="city" bind="cfc:blog.com.bindFcns.getcities({state})" value="#form.city#">
<option name="0">City</option>
</cfselect>
<cfinput type="submit" name="submit" value="Submit" id="Submit" />
</div>
</cfform>

-----------------
The Window Page ...
-----------------
<cfparam name="form.state" default="">
<cfparam name="form.name" default="">
<cfparam name="form.city" default="">

<cfoutput>
<p>
The State Submitted &##187; <cfoutput>#form.state#</cfoutput> <br> <br>
The City Submitted &##187; <cfoutput>#form.city#</cfoutput>
</p>
</cfoutput>

Result ... Nada ... Got a clue? :)

Comment 6 by Andy Sandefer posted on 10/20/2008 at 8:30 PM

@Edward
You really don't need to have the submit button and call submitForm() like that. Take the post and the onSubmit out of there and just call submitForm in the onClick of a button. It probably doesn't matter but you also don't need id and name values for the inputs - just use name and let CF do the rest (I doubt if this is causing any problems but it never hurts to simplify your code).
I really don't understand what's going on here but I haven't really seen the entire thing in action so I'll just add that Ajax.submitForm is typically called to pass form data to a handler/script page that interacts with the database. Do you really need to post this stuff? If not then get the values of the selects and send them as URL params through your cfwindow function.

Comment 7 by Edward Beckett posted on 10/20/2008 at 8:45 PM

@Andy ...
"Ajax.submitForm is typically called to pass form data to a handler/script page"

I'm attempting to send the form data to open in a CFWindow ...

My code's probably not the cleanest I'm sure ... sometimes I'm unsure what is and isn't necessary for a specific scenario and I end up just throwing in everything to "get it working" :)

I think my main problem is in the CallBack ... (showIt) But, I'm not sure ... thanks for your input.

Comment 8 by Andy Sandefer posted on 10/20/2008 at 8:54 PM

If this is some kind of step by step form entry then you can just save it in session vars and then load the page or you can use js to get the values and pass them as URL vars in the showIt function you invoke the cfwindow. You're trying to post to a page and then pull up the same instance of the page that you're posting to in a window object and I don't think that you can do that.

Comment 9 by Chris posted on 12/2/2008 at 9:58 PM

Can you use ColdFusion.Ajax.submitForm with a cfform format= flash?
<cfsavecontent variable="doThis">
getURL("javascript:submitFilterFormOff()");
</cfsavecontent>
<script language="javascript">
function submitFilterFormOff() {
ColdFusion.Ajax.submitForm('filterForm', 'set_ind_filter_cookies.cfm', callbackac,
errorHandlerb);
}

function callbackac(text)
{
ColdFusion.navigate('user_offline_assign_ind_filter_resultsnc_panel.cfm', 'divFilterResultsOff');
return
}

function errorHandlerb(code, msg)
{
alert(msg);
}
</script>

I get the javascript to fire but then get an alert saying form ID not found

Thanks for any help

Comment 10 by Raymond Camden posted on 12/2/2008 at 10:04 PM

No idea, but once again I'll echo my recommendation to avoid Flash Forms and just use 'real' Flex.

Comment 11 by Gavy posted on 12/17/2008 at 11:24 AM

Hi Ray! I am using the Same Stuff as you but i did get any relevant output.

does this console.log works only with firefox or with all browsers

Comment 12 by Andy Sandefer posted on 12/17/2008 at 7:39 PM

You need firebug (A very awesome firefox add-on)

http://getfirebug.com/

Comment 13 by Ray Meade posted on 4/27/2010 at 7:28 PM

Ray, is there full Flex support in CF8 and if so, how difficult would it be for me to learn Flex after using CF for a few years? I too have had many issues (albeit minor ones) using flash forms in CF, particularly with alignment (I have a small area that contains a photo of the member and some links and everything's pushed to the left and if I try to narrow the area to bring the right side in, it drops everything down instead) and form submission. (our people here are really annoyed that they can't just hit "Enter" to submit a form)

Comment 14 by Ray Meade posted on 4/27/2010 at 7:36 PM

Oh and I almost forgot...can I develop Flex apps. totally from within CF or do I need a Flex SDK or something?

Comment 15 by Raymond Camden posted on 4/30/2010 at 7:30 AM

"Flex support in CF8" can mean many things. They are completely different technologies. CF is a server side program, Flex generates Flash. Now they can definitely speak to each other. Flash and CF can communicate in multiple ways - the best being Flash Remoting.

I think Flex is easy to learn - but I find the latest Flex to be a bit harder to grok.

Ignore Flash Forms. Don't bother with em. Learn Flex instead. :)

You do not need CF to develop Flex apps. Period. All you need is the Flex SDK.

Comment 16 by Bryan posted on 7/16/2012 at 5:30 PM

OK I know this is an old post but this was the best description of how to solve this problem I found except for ONE SMALL POINT and that only concerns they way my pages work.

This example works great if your form action page refers to itself. In my case the action page is a different CF page where some heavy duty processing occurs.

So here's how I got my process to work:
From the initiating page the button that starts everything off:
<cfinput type="button" label="Save" value="Save" name="Save" onClick="assign();"/>

The java script:
function assignTheExaminer () {
ColdFusion.Ajax.submitForm('frmAssign', 'act_assign.cfm', callback, errorHandler);
}

My action page now does its thing with this addition which is the bit I want to return to the javascript:
<cfoutput>#res#</cfoutput><!--- res is the result I want to return to the javascript--->

Now my call back function in the javascript:

function callback(result){
if (result < 0) {alert('A problem occurred.');}
}//test the value to see if an error condition occurred.

I only had to handle the <cfoutput> tag in the action page to make it work.

Thanks, Ray for work you did 4 years ago.

Comment 17 by Bryan posted on 7/16/2012 at 5:33 PM

Yes - I see the typo in the name of the js function. Sorry. I was trying to be less detailed.