A few days ago I posted a link to a few new Spry demos including one that shows how to build custom columns in Spry. This is a pretty cool feature so I thought I'd whip up another demo so folks can really appreciate how handy this is. The idea is simple: You tell Spry to run code after the data is loaded and simply manipulate the data structure to add the new column. The new column can contain anything you want. This is great if you don't have control over the XML that your Spry page is using.
Consider an XML document that returns a ColdFusion date:
<cfsetting enablecfoutputonly="true" showdebugoutput="false"><cfcontent type="text/xml"> <cfoutput><people> <person> <name>Raymond Camden</name> <date>#now()#</date> </person> <person> <name>Jacob Camden</name> <date>#now()#</date> </person> </people></cfoutput>
This simple XML file will return two people. The date value for each will be set to the current time. If used as is, the date would look like this:
{ts '2006-12-27 09:20:35'}
Pretty ugly, eh? So lets make it nicer. First lets add an "Observer" to the Spry dataset. This tells Spry to run a function on any type of change in the data set:
data.addObserver(processData);
Now lets look at the processData function:
function processData(notificationType, notifier, thisdata) { if (notificationType != "onPostLoad") return;var rows = data.getData(); var numRows = rows.length;
for (var i = 0; i < numRows; i++) { var row = rows[i]; row.datepretty = myDateFormat(cfToDate(row.date)); } }
First note that we check the event type with the notificationType variable. (I based my function on the Adobe sample, so thanks go to them.) We get the data and the number of rows and then simply loop over the rows of data.
To add my custom column, I simply set a new value in the row. If I did:
row.goober = "foo";
Then the dataset would have a new column named goober with a static value of foo.
In my sample code, I wrote two custom functions, cfToDate, and myDateFormat. These are ugly functions that parse the date sent from ColdFusion and handle the formatting of the date. This could probably be done better, but you get the idea. I've included them in the zip (see Download link below).
Anyway - this is a very handy feature! Obviously you want to correct the XML server side if at all possible, but if you can't, this is a great way to handle it.
Archived Comments
the addition of custom columns was enough for me to convince a client to switch their reporting to being mostly spry driven. When I showed them the custom highlighting and calculations and then the speed increase from using an xml file vs adhoc querying every time (p.s. re sorting the columns was re-hitting the db WITHOUT caching in place :O ) they love me now :D
You say that it's best to make the changes to the XML server side if possible which makes sense. What if I'm pulling a query with datestamps from a MySQL database, should I modify the query before running it through toXML and sending it to Spry? It probably makes sense to do the dateFormat during the conversion from Query to XML.
I could also have the database format the date, but I doubt that I should be hard coding the date/time formats into the queries.
I do that Dan. I've tried to do date formatting in JS, and it's SO much easier in CF.
Kind of replying to my own comment...
I'm having one of those days where I am really hoping to find, "The Most Obvious Way" and just get my project completed. But this post just got me thinking that date formatting can be done anywhere along the line with SQL, CF, or Javascript and there seems to be pros and cons to each. It's even more confusing when you're trying to stay within the confines of MVC. (And I'll bet we'll have a way to do it in CSS in a few years as well. ;-)
Following MVC, the date formatting should probably be done in the Javascript template, but that's going to be the slowest and most cumbersome method. You're right that it's easier in CF (or even SQL), and it's probably faster since the formatting can be cached.
But, your point here was just to show that it could be done in Spry/Javascript, which is great. It's good to be knowledgeable about and to consider the different methods.
So thank you for sharing this info. I'll continue looking for "The Most Obvious Way" with the rest of the project. ;-)
We are just going to use ColdFusion at our company (http://www.munsoft.com/) but thank you for post.