ColdFusion 8 - JavaScript JSON Encode/Decode API
Posted By : todd sharp Posted At : July 4, 2007 2:20 PM Posted In: Ajax, ColdFusion
0
ColdFusion 8 ships with a handful of new functions and API along with the new AJAX features to handle different scenarios that you may come across. For example we have the built in serializeJSON and deserializeJSON functions available that allow us to take a ColdFusion array and encode as JSON (and vice versa). These functions are very helpful when using AJAX functionality (for example, working with Spry datasets) as they allow us to take a native CF data type and almost seemlessly hand it off to JavaScript.
What about when we have less control over the data being returned? For example we use ColdFusion.Ajax.submitForm() to post form data to an action page - we receive the HTTP resopnse body back with that call but as far as CF is concerned the data is pretty much just a string. Even if we try to use cfcontent we'd still just get back a string representation of whatever data we tried to send back to the caller.
I've had a few discussions with folks and while the use cases involved seem rather few and far between, the CF engineers have a few functions that will be available in the final release to deal with these edge cases. I'll quote Ashwin Matthew since his explanation explains it best (PS - I have been giving permission to blog this):
With the final release, we will have new JavaScript functions to encode and decode JSON:1. ColdFusion.JSON.encode(
) Encodes the supplied variable and returns it as a JSON string. 2. ColdFusion.JSON.decode(
) Decodes the supplied JSON string and returns an equivalent JavaScript variable. If the JSON string is "secure", i.e., has the configured prefix, the prefix will be stripped to allow for proper decoding. Wondering about "secure" JSON? More on that later - with the final release, we'll have support for protecting your JSON web services from the attacks outlined here: http://www.fortifysoftware.com/servlet/downloads/user/JavaScript_Hijacking.pdf
So consider the following code:
cb = function(resp){
var respContainer = document.getElementById('respContainer');
respContainer.innerHTML = resp;
}
sb = function(){
ColdFusion.Ajax.submitForm('foo', 'ajaxsubmit.cfm', cb)
}
</script>
<cfform name="foo" onsubmit="sb(); return false;">
<cfinput type="text" name="testinput" />
<cfinput type="submit" name="submit" value="submit">
</cfform>
<div id="respContainer">
</div>
And the action page:
<cfparam name="returnStruct" default="#structNew()#">
<cfif len(form.testinput)>
<cfset returnStruct.saved = true>
<cfset returnStruct.msg = "thanks...">
<cfelse>
<cfset returnStruct.saved = false>
<cfset returnStruct.msg = "you didn't input anything dude...">
</cfif>
<cfcontent type="application/json" reset="true">
<cfoutput>#serializeJSON(returnStruct)#</cfoutput>
Given that code if we were to run the form and click submit without entering anything we'd get the following string placed inside of our response container:
In the final release of CF 8 we'll be able to change our callback handler to this:
var respContainer = document.getElementById('respContainer');
var respStruct = ColdFusion.JSON.encode(resp);
if(resp.saved){
respContainer.innerHTML = resp;
}
else{
//do stuff...
}
}
And parse that string into a struct so that we can conditionally evaluate the next step based on whether or not the form was saved.
It's important to note that converting the entire example I have here to a CFC/cfajaxproxy based approach negates the need for any of the logic above. If our CFC returned a struct and we submitted it with via a cfajaxproxy method we'd have a serialized struct automagically. But that's another blog post...


