Solved

Coldfusion Ajax CFC - returning data

Posted on 2013-01-14
17
916 Views
Last Modified: 2013-01-15
Hi,
I need to write a quick remote cfc for a client side JQuery request for 4 fields on a table.

I will get 1 parameter sent to me "image file name" and I will return 4 columns from a table to be moved by the Jquery to 4 text fields.

<cffunction name="imageData"  access="remote" returnType="any" output="no">
      <cfargument name="imageKey" type="any" default="">

<cfquery name="getImage" datasource="myappdsn">
  Select column1, column2, column3, column4
   from Slide  where imageFile = #arguments.imageKey#

<CFreturn ??????>

</cffunction>

Open in new window


Q:   How do I return the data to the Jquery call?  Do I create a JSON string?  How do I do that?

For extra credit, how does the JQuery code parse this data to populate 4 text fields on the page?

Thanks in advance,
hefterr
0
Comment
Question by:hefterr
  • 6
  • 6
  • 5
17 Comments
 
LVL 10

Assisted Solution

by:stu215
stu215 earned 200 total points
ID: 38774914
<cffunction name="imageData"  access="remote" returnType="any" output="false" returnformat="JSON">


<!--- convert to json --->
 <cfreturn serializeJSON(yourResult)>

You can return data in a variety of ways it just depends on how you read it in when it gets back.
( Firefox with Firebug installed helps a lot for debugging and seeing return results. )

You could also do:
<cffunction name="imageData"  access="remote" returnType="query" output="false" returnformat="JSON">

<cfreturn yourQueryName>

The jQuery.get function should handle your restults:
http://api.jquery.com/jQuery.get/

 url - the cfc you are submitting to
data - being sent to cfc
callback - what function to run or to do when the data comes back
"Json" - the data type being transmitted

jQuery.get(url, data, callback, "json");
0
 
LVL 52

Accepted Solution

by:
_agx_ earned 300 total points
ID: 38775002
(I'm not a jquery guru, but since I had already written this starter example before seeing stu's response, may as well post it ;-)

Test

/test/MyComponent.cfc
<cfcomponent>

	<cffunction name="imageData"  access="remote" returnType="any" output="no">
     	<cfargument name="imageKey" type="any" default="">

		<cfset var result = {} />
		<cfset var row = "" />
		
		<!--- (testing only) simulate your db query --->
		<cfset var getImage = queryNew("")>
		<cfset queryAddColumn(getImage, "column1", listToArray("Value 1"))>
		<cfset queryAddColumn(getImage, "column2", listToArray("Value 2"))>
		<cfset queryAddColumn(getImage, "column3", listToArray("Value 3"))>
		<cfset queryAddColumn(getImage, "column4", listToArray("Value 4"))>
		
		<cfloop query="getImage">
			<!--- MUST use struct["keyName"] syntax to preserve case ---> 
			<cfset row = {}>
			<cfset row["column1"] = column1 >
			<cfset row["column2"] = column2 >
			<cfset row["column3"] = column3 >
			<cfset row["column4"] = column4 >
			<cfset result["data"] = row>
		</cfloop>
		
		<cfreturn result>
	</cffunction>
</cfcomponent>

Open in new window


<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>	
<script type="text/javascript">
$(document).ready(function() {
		$("#testButton").bind("click",function() {
			var key = document.getElementById('imageKey').value;
			var request = $.ajax({url: "/test/MyComponent.cfc?method=imageData&returnFormat=json"
								, type: "get"
								, dataType: "json"
								, data: {imageKey : key}
					});
			request.done( function(data) {
				populateFields(data);
			});
			request.fail( function(jqXHR, status) {
				alert("Failed: "+ status);
			});
		});
	});

function populateFields(response) {
	alert(response.data);
	if (response.data) {
		$("#field1").val(response.data.column1);
		$("#field2").val(response.data.column2);
		$("#field3").val(response.data.column3);
		$("#field4").val(response.data.column4);
	}
}	
</script>

</head>
<body>
	imageKey <input id="imageKey" type="text">
	<input id="testButton" type="button" value="Test" ><hr>
	
	<input id="field1" type="text"><br>
	<input id="field2" type="text"><br>
	<input id="field3" type="text"><br>
	<input id="field4" type="text"><br>
</body>
</html>

Open in new window

0
 
LVL 1

Author Comment

by:hefterr
ID: 38776474
@agx,
1)  Could you give me an overview of what you are building.  It looks like a CF structure "result" that has one key item (result.data)?  This contains another structure called "row" which contains row.column1, row.column2,row.column3 and row.column4?

Q:  Why does this ned to be built this way?

Q:  How can I see the result.  Can I use CFHTTP in a test program?

Q:  Do I need to indicate JSON in my CFC anywhere?

2)  Is the reference to :
                  request.done( function(data) {
                        populateFields(data);
                  });

tie back to the structure "data" or is that a JQuery special reference?

Thanks!
hefterr
0
 
LVL 52

Expert Comment

by:_agx_
ID: 38776908
(Sorry I got caught up in other stuff...)

an overview of what you are building

"row" is just a temporary value used in construction. The actual result returned is a structure that contains a key named "data". "data" is itself a structure which contains 4 keys - one for each of the columns in your query.   ie  result.data.column1, result.data.column2, etc...  Here's what the json looks like

{"data":{"column4":"Value 4","column2":"Value 2","column3":"Value 3","column1":"Value 1"}}

Open in new window



Q:  How can I see the result.  Can I use CFHTTP in a test program?

You can view the results in your browser. Just adjust the url to match the path of your cfc:

   http://localhost/test/MyComponent.cfc?method=imageData&returnFormat=json&imageKey=someValueHere

Q:  Do I need to indicate JSON in my CFC anywhere?

You can, but don't *need* to. It's already done in the jquery url by adding the param:

           &returnFormat=json

(Doing it via url makes the function more flexible)

Q:  Why does this ned to be built this way?

Again, you don't *have* to build it that way. I chose that structure based on some assumptions about your process, like query returns 1 row of data, etc.. But you could easily structure it differently.  

tie back to the structure "data" or is that a JQuery special reference?

Neither. The name "data" is just a coincidence. You can assign any variable name, for example, I could have used "foo":

                  request.done( function(foo) {
                        populateFields(foo);
                  });

> alert(response.data);

BTW, you can remove that line. It was just for testing.
0
 
LVL 1

Author Comment

by:hefterr
ID: 38778329
@both

Stu simply returned the query itself.  Does this change the JQuery fielding the results?  What type of JSON does this produce?

agx packaged a structure.

Is there a good reason for one versus theother.

I really learned a lot from this post.  This is my first time using our own JQuery/AJAX.

hefterr
0
 
LVL 10

Expert Comment

by:stu215
ID: 38778923
Check out this link which explains the "serializeJSON" function and shows what the query return would look like: ( has an example + the output )

http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=functions_s_03.html
0
 
LVL 1

Author Comment

by:hefterr
ID: 38778965
Hi stu215.
I was under the impression that the returned data would automatically undergo a conversion to JSON if the calling JQuery script indicated as such.

But the link was helpful to how the conversion is done for different data structures in CF.

hefterr
0
 
LVL 10

Expert Comment

by:stu215
ID: 38779007
I didnt have an example at the time but this is what a straight query return would look like:

<cffunction name="getEmps" output="false" access="remote" returntype="any" returnformat="JSON">
        <cfargument name="myDeptID" type="string" required="yes" default="">

        <cfquery name="getPeeps" datasource="general" maxrows="4">
           ... my Query ...
          </cfquery>

        <cfreturn getPeeps>
 </cffunction>  

The Results:

{"COLUMNS":["MYNAME","USERNAME","CUST_ID","FLAG"],"DATA":[["Abd, sha","abdsha444",null,"Y"],["Abc, Mike","Abc666 ",null,"Y"],["Ada, Jay","Ada555 ",null,"Y"],["Air, Kat","AirK222 ",null,"Y"]]}
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 52

Expert Comment

by:_agx_
ID: 38779379
Does this change the JQuery fielding the results?  What type of JSON does this produce?

The JSON is the same, only the structure of the result ie keys are different.

agx packaged a structure...
Is there a good reason for one versus the other.


You can do either. The advantage of just returning a query is it's simpler to code on the CF side. But the disadvantage is CF automatically converts all the keys to upper case, which is non-standard. (By that I just mean different than most of your typical API's, but the json is still perfectly valid). Because javascript is case sensitive, the consuming code must also use all upper case. Both work, its just a matter of what result you want.

I was under the impression that the returned data would automatically undergo a conversion to JSON if the calling JQuery script indicated as such.

It does. Adding   &returnFormat=json to the URL automatically converts the result to JSON.  So you can use the function multiple ways. Just add the url param when you want JSON. You could also use serializeJSON inside the function, but then it will always return JSON, making it a little less flexible.
0
 
LVL 1

Author Closing Comment

by:hefterr
ID: 38779407
Thanks for your help on this.  I may have other questions - but I'll open them up in another question or to the JQuery forum if needed.
0
 
LVL 52

Expert Comment

by:_agx_
ID: 38779521
Welcome.

     > CF automatically converts all the keys to upper case

(Edit) Two things I forgot to stress.  That applies to any structure. The only way to force CF to preserve the case of structure keys is to use this syntax (Dot notation *won't* work)

               <cfset yourStruct["keyName"] = "something">

Second,  the "&returnFormat=json" param has nothing to do with jquery. It's pure CF. CF sees that parameter in the URL and automatically converts the response to json format.
0
 
LVL 1

Author Comment

by:hefterr
ID: 38780038
@agx,
The only way to force CF to preserve the case of structure keys
This is a very lame question, but do you mean the "case" of the key name or the "case" of the key value.  I assume you are referring to the case of the value.
0
 
LVL 10

Expert Comment

by:stu215
ID: 38780062
Agx is referring to how the data is returned from the CFC:

This is how it should look:
{"data":{"column4":"Value 4","column2":"Value 2","column3":"Value 3","column1":"Value 1"}}

Coldfusion would make it all caps ( Caps are not standard ) and programs will have issues.

You can kinda see this from my data return using CF:
{"COLUMNS":["MYNAME","USERNAME","CUST_ID","FLAG"],"DATA":[["Abd, sha","abdsha444",null,"Y"],["Abc, Mike","Abc666 ",null,"Y"],["Ada, Jay","Ada555 ",null,"Y"],["Air, Kat","AirK222 ",null,"Y"]]}
0
 
LVL 52

Expert Comment

by:_agx_
ID: 38780067
The key name. If you create a structure with dot notation:
              <cfset myStruct.someKeyName = "foo">

When CF converts it to json, it will look like something like this:
             { SOMEKEYNAME: "foo" }

But if you used this syntax:

              <cfset myStruct["someKeyName"] = "foo">

CF will preserve the exact case of the key name and the json result will be:

             { someKeyName: "foo" }
0
 
LVL 52

Expert Comment

by:_agx_
ID: 38780070
Oops, sorry guys.  Took too long typing and our responses overlapped,
0
 
LVL 10

Expert Comment

by:stu215
ID: 38780081
Sall good :-P

-- You can handle it on the return side if you want but generally its easier to return standard data & to do any processing to your data before returning it.
0
 
LVL 1

Author Comment

by:hefterr
ID: 38780321
You guys re GREAT!  Big help getting into CF/JQuery/AJAX.  I am working with a front end colleague doing the JQuery - but she is a bit new to this also.  So thanks again,

hefterr
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

The technique is by far very Simple! How we can export the ColdFusion query results to DOC file?  Well before writing this I researched a lot in Internet but did not found a good Answer anyways!  So i thought now i should share my small snippet w…
CFGRID Custom Functionality Series -  Part 1 Hi Guys, I was once asked how it is possible to to add a hyperlink in the cfgrid and open the window to show the data. Now this is quite simple, I have to use the EXT JS library for this and I achiev…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

26 Experts available now in Live!

Get 1:1 Help Now