I recently started playing with Adobe Spry while evaluating some AJAX options for work. In an attempt to cover the basics of a CRUD application that uses Spry, I made the first step of displaying records from a database.
Spry is great at reading data from XML and since we can’t read data direct from the database, we need a coldfusion component. The CFC will read the database, loop from records and build an XML output. Here is my very basic CFC:
<cfcomponent>
<cffunction name=”FindAll” access=”remote” returntype=”xml” output=”no”>
<cfquery name=”getEmp” datasource=”#dataSrc#”>
SELECT firstName, lastName, officePhone, id
FROM employees
</cfquery>
<!— Convert Query to xml —>
<cfprocessingdirective suppresswhitespace=”Yes”>
<cfcontent type=”text/xml; charset=utf-16″>
<cfxml variable=”xmlobject”>
<response>
<data>
<cfoutput query=”getEmp”>
<row>
<id>#id#</id>
<firstName>#firstName#</firstName>
<lastName>#lastName#</lastName>
<officePhone>#officePhone#</officePhone>
</row>
</cfoutput>
</data>
</response>
</cfxml>
<!— Convert back to a string —>
<cfset myvar=toString(xmlobject)>
<cfset mynewvar=replace(myvar, “UTF-8″, “utf-16″)>
</cfprocessingdirective>
<cfreturn mynewvar>
</cffunction>
</cfcomponent>
I ran into some compatibility issues with the XML document created by the CFC. Initially I kept it the same as my flexbuilder example, however, the XML produced wasn’t good enough for Spry? Interestingly, I needed to be a little more strict in my XML creation for Spry to accept it as a valid document. Funny that two Adobe products would have different criteria for what is an acceptable XML document. The only way I could make it work with Spry short of actually pointing to a static XML file was to use the <cfxml> tag to create my document. Flexbuilder did not require this and seems to be more loose in it’s requirements.
The CFC can be called directly in your browser and display the XML output:
http://brad.melendy.com/projects/webservice/employees.cfc?method=FindAll
Now we need only create our page with the Spry libraries like so:
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” xmlns:spry=”http://ns.adobe.com/spry”>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
<title>Untitled Document</title>
<script src=”../../../SpryAssets/xpath.js” type=”text/javascript”></script>
<script src=”../../../SpryAssets/SpryData.js” type=”text/javascript”></script>
<script type=”text/javascript”>
<!–
var ds1 = new Spry.Data.XMLDataSet(“http://brad.melendy.com/projects/webservice/employees.cfc?method=FindAll”, “response/data/row”,{sortOnLoad:”id”,sortOrderOnLoad:”ascending”,distinctOnLoad:true});
//–>
</script>
</head>
<body>
<div spry:region=”ds1″>
<table>
<tr>
<th spry:sort=”id”>Id</th>
<th>FirstName</th>
<th>LastName</th>
<th>OfficePhone</th>
</tr>
<tr spry:repeat=”ds1″ spry:setrow=”ds1″>
<td>{id}</td>
<td>{firstName}</td>
<td>{lastName}</td>
<td>{officePhone}</td>
</tr>
</table>
</div>
</body>
</html>
You will notice that on the line where we create our new dataset object, I use the full URL to the CFC. This could be a relative link to the file on the same web server, but it needn’t be, in fact it can reside on an entirely different server. In this example, our three important areas include the two Spry javascript libraries, xpath.js and SpryData.js, the creation of the dataset, “ds1″ and then finally the output of the spry:region. I have set the ID column to be sortable with “spry:sort”. The headers are static, and then “spry:repeat” is used to display all the records just like <cfoutput query=”"> would do. Here is the working demo:
http://brad.melendy.com/projects/ajax/spry/test2.cfm
It isn’t pretty as there is no style but it does the job and only takes about 15 minutes from start to finish. I’ve included all the files for the working demo here:
http://brad.melendy.com/projects/ajax/spry/spry-dataset-cfc.zip
Just extract onto your web server and make sure that you create the DB using the included .SQL file and you will need to setup your datasource in CF.