How can I use a ColdFusion function that is on the same page as a script?

earwig75
earwig75 used Ask the Experts™
on
I normally call a cffunction with Ajax in ColdFusion like the below example. I want to do the exact same thing, but instead of having the cffunction on a separate .cfc page, I want to have it right on the .cfm page that I am calling it from. I want the <script> and CFFunction on the same page.

Can someone help?

<cfajaxproxy cfc="/mySite/myDir/myCFC" jsclassname="jsobj">

<script>
	function myFunction(){
	var somethingOne= 'somethingOne';
	var somethingElse = 'somethingElse';
	var cfcAsAjax = new jsobj();
	cfcAsAjax.myCFFunction(somethingOne,somethingElse);
	}
</script>

On the .CFC page, I just have a normal CFFunction:

<cffunction name="myCFFunction" output="false" access="remote">
	<cfargument required="true" type="numeric" name="somethingOne" />
	<cfargument required="true" type="String" name="SomethingElse" />
..........

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Most Valuable Expert 2015

Commented:
Any specific reason you can't use a separate cfc?  AFAIK, CFAjaxProxy only works on cfc's, so it won't work with .cfm pages.   Technically I suppose you could do something similar with jquery, but ... I wouldn't advise it. You'd have to add conditionals to the page to do one thing when it was an ajax request, and something else the rest of the time, which is very messy and error prone IMO...

Author

Commented:
There's no reason, I just wanted to keep it simple with 1 less page. I like to use .cfc files when I plan on reusing code. Thank you.
Most Valuable Expert 2015
Commented:
Well, I don't think single page approach is possible in this specific case. At least not with cfajaxproxy.

In this one case, 2 files is simpler IMO :) At least from a maintainability perspective.  Forcing a single script to serve dual purposes ie return text/html AND ajax/wddx/xml will make it a lot more complex and error prone.  Ajax stuff can be incredibly picky about things like extra white space, etc... and those are much harder to control from a .cfm script.
Most Valuable Expert 2015

Commented:
I was curious if using jquery might be simpler than I was thinking, so I did a quick comparison of the CFAjaxProxy + 2 scripts versus jquery + 1 script.  It quickly came back to me why doing ajax calls to .cfm scripts is so painful ;-)  

What you have already, ie CFAjaxProxy + 2 scripts is much cleaner. No contest:


CFAjaxProxy + 2 scripts

Script1.cfm
<cfajaxproxy cfc="myCFC" jsclassname="jsobj">
<script type="text/javascript">
	function myFunction(){
		var somethingOne = 1;
		var somethingElse = 'somethingElse';
		var cfcAsAjax = new jsobj();
		var response = cfcAsAjax.myCFFunction(somethingOne,somethingElse);
		alert("RESPONSE \n"+ response.MESSAGE);
	}
</script>

<form>
	<input type="button" value="Test" onClick="myFunction()">
</form>

Open in new window


MyCFC.cfc
<cfcomponent>
	<cffunction name="myCFFunction" output="false" access="remote" returntype="struct">
		<cfargument required="true" type="numeric" name="somethingOne" />
		<cfargument required="true" type="String" name="SomethingElse" />
		<cfset Local.result.message = "somethingOne = "& arguments.somethingOne &" somethingElse="& arguments.SomethingElse />
		<cfreturn Local.result />
	</cffunction>
</cfcomponent>

Open in new window



Jquery + single script (yikes...)
<!--- This code MUST be at the top of the page --->
<!--- Suppress extra white space to avoid ajax problems.  --->
<!--- Debugging must be off or it will break the request --->
<cfsetting enablecfoutputonly="true" showdebugoutput="false">
<cfif structKeyExists(FORM, "method") AND FORM.method eq "myFunction">
	<!--- returning a response for demo purposes --->
	<cfset response = {message = myCFFunction(argumentCollection=FORM)}>
	<cfcontent type="application/json" reset="true">
	<cfoutput>#serializeJSON(response)#</cfoutput>
	<!--- must abort or the ajax request will break <cfabort>
</cfif>

<cfsetting enablecfoutputonly="false">
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
<script type="text/javascript">
	function myFunction(){
		var firstVar = 1;
		var secondVar = 'somethingElse';
		$.ajax({
		    // update path to script
			url: 'allInOneScript.cfm'
			, method: 'POST'
			, data: { somethingOne: firstVar, SomethingElse: secondVar, method : 'myFunction' }
			}).done(function(response){
			    // do something on success
				alert("RESPONSE \n"+ response.MESSAGE);
			}).fail(function (jqXHR, textStatus) {
			    // do something on failure
				alert("Failure ");
				console.log(jqXHR);
			});
  } 
</script>

<form>
	<input type="button" value="Test" onClick="myFunction()">
</form>

<!--- technically functions can be defined anywhere in the script. placing outside ajax code for clarity --->
<cffunction name="myCFFunction" output="false" access="remote">
	<cfargument required="true" type="numeric" name="somethingOne" />
	<cfargument required="true" type="String" name="SomethingElse" />
	<cfreturn "Values received: somethingOne = "& arguments.somethingOne &" somethingElse="& arguments.SomethingElse />
</cffunction>

Open in new window

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial