At work we have been experimenting with various methods of retrieving data from the server-side. The most traditional AJAX approach is by using the XMLHTTPRequest object (asynchronous or synchronous) as the transfer mechanism and XML to describe the data.
Another method is using JavaScript SCRIPT tags as the transfer mechanism, and JavaScript Object Notation (JSON) or regular JavaScript syntax to “describe” the data.
You can achieve this by dynamically creating JavaScript SCRIPT tags, where the source (src) is a ColdFusion template that generates JavaScript.
I think that this is the easiest and quickest method of AJAX, and it really allows you to reuse your existing business logic quickly.
1. Static JavaScript file dynamically creates a SCRIPT tag via the DOM
2. The source of the SCRIPT tag is the ColdFusion template that dynamically creates the JavaScript code.
As an example, let’s retrieve a bunch of artists from the sample artist database that comes with ColdFusion MX. I’ll then draw the artists to an existing HTML table using the DOM.
By the way, this code only works in Internet Explorer (but could be easily modified to work in Firefox). Given it is an example, I have a certain license! 
display.html
This is a sample HTML page that contains the empty table ready for population. Upon first load, the table is automatically populated.
<html>
<head>
<title>JSON Test</title>
<script src=”artists.js”></script>
</head>
<body>
<a href=”javascript:getArtists()”>Call getArtists() method — appends to table!</a>
<br/><br/>
<table id=”artistTable”>
<caption>Artists</caption>
<thead>
<tr>
<td>ID</td>
<td>Last Name</td>
<td>First Name</td>
<td>City</td>
</tr>
</thead>
</table>
<script>
getArtists();
</script>
</body>
</html>
artists.js
This JavaScript file contains methods that will dynamically create the SCRIPT tag. The src attribute of the SCRIPT tag is the getData.cfm ColdFusion template, which creates the JavaScript data.
The populateUI method (which populates the table with the data) is only called once the SCRIPT tag’s readyState has changed to “loaded”.
function getDataFromServer(id, url, callback)
{
oScript = document.getElementById(id);
var head = document.getElementsByTagName(”head”).item(0);
if (oScript)
{
// Destory object
head.removeChild(oScript);
}
// Create object
oScript = document.createElement(”script”);
var dtRf = new Date();
oScript.setAttribute(”src”,url + “?rf=” +dtRf.getTime());
oScript.setAttribute(”id”,id);
head.appendChild(oScript);
if (oScript.readyState!=”loaded”)
{
oScript.onreadystatechange = function()
{
if (this.readyState == “loaded”)
{
eval(callback);
oScript.onreadystatechange = null;
}
}
}
else
{
alert(’Cannot load data!’);
}
}
function getArtists()
{
getDataFromServer(”artistData”,”getData.cfm”,”populateUI()”);
}
function populateUI()
{
oTable = document.getElementById(”artistTable”);
// Loop over the data in the JS array, and add to table
for (var i=0; i < aData.length; i++)
{
// Create a new TR element
oTR = oTable.insertRow();
// Create a call for each element in struct
oTD = oTR.insertCell();
oTD.innerHTML = aData[i].artistid;
oTD = oTR.insertCell();
oTD.innerHTML = aData[i].lastname;
oTD = oTR.insertCell();
oTD.innerHTML = aData[i].firstname;
oTD = oTR.insertCell();
oTD.innerHTML = aData[i].city;
}
}
getData.cfm
This ColdFusion template performs a query on the artist database. The query is then converted to an Array of Structures (using QueryToArrayOfStructures from cflib.org), and then converted to JavaScript using the CFWDDX tag.
I am not *really* using JSON here. But, by using the bult-in ColdFusion JavaScript conversion functionality in the CFWDDX tag, you achieve the same result, it’s just not as light-weight.
<cfsetting enablecfoutputonly="true">
<cfquery datasource=”cfartgallery” name=”qData”>
SELECT *
FROM artists
ORDER BY lastname, firstname
</cfquery>
<cfwddx action=”cfml2js” input=”#QueryToArrayOfStructures(qData)#” output=”jscontent” toplevelvariable=”aData”>
<cfoutput>#jscontent#</cfoutput>
There you have it! I’m pretty sure this code shall work, and I welcome any comments or improvements. It was put together pretty quickly!