Posted in | Posted on 06-02-2006 | 17,972 views
I'm a bit late to the party, but I finally took some time to check out the Spry framework, Adobe's answer to the AJAX craze. I haven't been that impressed with AJAX. I mean, it's useful, yes. Very useful. But it's also kind of old and so it isn't really new to me. I've been thinking about learning a bit of AJAX for use in the back end of BlogCFC. I took some time early this morning to look at Spry.
Wow.
I mean, seriously, Adobe, could you make this a bit simpler? I think it was harder to put my shoes on this morning. Consider the following simple example (and this is not 100% complete, but it gives you an idea of how short the code is):
2<script type="text/javascript" src="includes/SpryData.js"></script>
3<!-- load the xml, notice the xpath support -->
4<script type="text/javascript">
5var dsHatches = new Spry.Data.XMLDataSet("dharma.xml", "hatches/hatch");
6</script>
7
8<!-- now bind it to an html table -->
9<div id="Hatches_DIV" spryregion="dsHatches">
10<!--Display the data in a table-->
11<table>
12<tr>
13<th>Hatch</th>
14<th>Icon</th>
15<th>Active</th>
16</tr>
17<tr spryrepeat="dsHatches">
18<td>{hatch}</td>
19<td><img src="/images/dharma/{icon}"></td>
20<td>{active}</td>
21</tr>
22</table>
23</div>
So the first line loads the data set from XML. It uses XPath to translate this into a data set. I can then bind it to a table by using the spryregion and spryrepeat tags. Notice the use of bound variables inside.
For a more complete demo, check out the Spry front end version of BlogCFC. Make sure you view source on that.
I did run into one interesting problem. I knew that I needed XML, so I knew I couldn't just use my blog's main CFC. I wrote a new CFC that would handle the few methods I needed and return them as XML. (This was rather boring, but I did make two cool little functions you may like, arrayToXML and queryToXML. Both of these already exist on CFLib I think, but I wrote my own for the heck of it.)
I thought that was all I needed, but it wasn't loading. Then I tried making the same request Spry was, and I found out what it was. ColdFusion was wrapping my response in WDDX. So what could I do? (I wish CFC's had an option to NOT wrap the result in WDDX and just return it "bare".) I wrote another file, this time a CFM. It simply acted as a proxy to call my other proxy CFC. It then returned the XML correctly.
I think I spent more time in ColdFusion then I did in JavaScript. That to me is a good thing. It means Adobe really did a darn good job with this framework. This is exactly the kind of thing I can see using in real world applications.
I definitely recommend my readers to take a few minutes and download the framework. I think you will find it worth your while.


Thanks to Massimo (http://www.massimocorner.com):
http://www.olimpo.ch/tmt/tag/spryxml/
http://www.olimpo.ch/tmt/tag/sprydataset/
/foo.cfc?cfc=path.to.cfc&method=X&arg1=val1
Etc.
I'll need to spend time with their dynamic master/detail feature before I get too excited.
Looking over their documentation, there's probably a way to create a CF custom tag that accepts a query, and two sets of column names (master cols and detail cols) and automatically generates a dynamic master/detail page similar to their examples. Now THAT would be nice. ;-)
Thanks for bringing this topic up again. I have been meaning to spend more time looking over SPRY.
http://www.kylehayes.info/sendFeed/spryeg.cfm
As you can see, because I don't call the dataset initially, I get an error. And the only way to prevent this error is to create a dataset, that simply has no data in it (at least from what I have found).
var dsStatus = new Spry.Data.XMLDataSet("", "status/message");
where I am not passing a url but I am passing the arguments that desribe how the data will be coming in.
Ray, I found this problem myself in CF7 when I was playing around with ajax. So in CF7.1 I modified the return behavior of CFCs. As you discovered, by default if you request a CFC from a URL all values are wrapped in WDDX (this way you can return complex types). However, now there is one exception. If you set the ReturnType="XML" we won't wrap it in wddx.
HTH
Damon
Thanks.
New question regarding formatting of content. How? it looks like the typical html tags are not interpreted. Are there any work arounds for this?
Thanks!
http://www.tusker.com/Spry_P1_3_08-11/samples/Zugg...
Currently there is some additional garbage because it was pasted directly from word but it shows what I'm am referrering to. All of the HTML tags are treated as text.
<cfset txt = "<![CDATA[" & txt & "]]" & ">">
I basically use this to wrap text that may have html. For text that won't have html, I don't wrap it like that. I do this instead:
<cfset txt = xmlFormat(txt)>
I can't take credit for this - I believe Adobe posted a response to me on the forums.
<cfset fieldsList = LCase(attributes.variable.columnList)>
<cfset xmlData = "">
<cfloop query="attributes.variable">
<cfset jsRow = "">
<cfloop index="x" list="#fieldsList#">
<cfset jsRow = jsRow & "<" & x & ">" & XMLFormat(attributes.variable[x][attributes.variable.currentRow]) & "</" & x & ">">
</cfloop>
<cfset xmlData = xmlData & "<#attributes.rownode#>" & jsRow & "</#attributes.rownode#>" & Chr(13)& Chr(10)>
</cfloop>
I saw your other posting where you implemented the CDATA but as the structure of this is slightly different, I am unsure how to include it. I tried replacing the XMLFormat but it puked.
<cfset jsRow = jsRow & "<" & x & ">" & XMLFormat(attributes.variable[x][attributes.variable.currentRow]) & "</" & x & ">">
<cfset fieldsList = LCase(attributes.variable.columnList)>
<cfset xmlData = "">
<cfloop query="attributes.variable">
<cfset jsRow = "">
<cfloop index="x" list="#fieldsList#">
<cfset jsRow = jsRow & "<" & x & ">" & <![CDATA[" & attributes.variable[x][attributes.variable.currentRow] & "]]></" & x & ">">
</cfloop>
<cfset xmlData = xmlData & "<#attributes.rownode#>" & jsRow & "</#attributes.rownode#>" & Chr(13)& Chr(10)>
</cfloop>
<cfset jsRow = jsRow & "<" & x & "><![CDATA[" & attributes.variable[x][attributes.variable.currentRow] & "]]></" & x & ">">
http://www.tiobe.com/index.htm?tiobe_index
grow up.
I've finally sat down with Spry this morning and have been working it, testing this, trying that etc. So far, so good. I really like that I'm seeing and I can see how incredibly useful this is.
One question:
What's a nice way (or good way) to create something like a nested/grouped output?
I've got a dataset that contains item names, they constitute 'groups' of data. Each item in turn has a number of locations and finally details.
So if I want to output and group by item name, then location then display the details what's your observation on best route with Spry?
If there's an annoyance, it's that the Spry version of the dynamic table doesn't have paging built in.
@Dan: I've heard this. I downloaded the demo just to see it - but I haven't tried it yet.
Spry does support paging - it may not be in an easy DWMX wizard though.
Hmmm. Obviously this is rhetorical. ...now back to your regularly scheduled programming. ;-)
Does that make sense? Thank you for the link though - I'm going to blog it a bit later.
[Add Comment] [Subscribe to Comments]