Ask a Jedi: Trouble with ColdFusion.Ajax.SubmitForm
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 to
a 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 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: Now when I ran the code I got a nicely trimmed response. I added one more line to set the result value:<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>document.getElementById("result").value = result.trim();Comments
The PHP link made me chuckle but the Lohan reference was the real comedy here folks!
Thanks a bunch!
Andy
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? :)
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.
"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.
<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

