CF8 Ajax Feed Reader Redux

There's been a lot of discussion recently about the page size being generated by the CF8 Ajax components and most of it has been really positive with Adobe assuring us that they're working on minimizing the YUI, Ext and Spry libs before final release.

I've been having a great exchange with Damon and Ashwin of Adobe about this and sent the code for my version of Todd Sharp's CF8 Feed Reader app. Todd did a great job leveraging CF8's Ajax widgets and when I saw the results, I was truly floored by the simplicity of the implementation. Well, Ashwin really stepped it up and took it a step further. With a few tweaks, he was able to take it a step further and come up with a VERY clean and concise version of the feed reader. I was shocked at how clean this was. He also managed to get it down from 717k to 242k. He also mentioned that the Ajax indicator (loading.gif) had not been optimized (107k) and he was going to update that as well. That would probably bring the page size down another 80-100k! That is amazing work Ashwin!!

Below is Ashwin's code:

index.cfm:

Notice that he uses the CFDIV tag to dynamically bind the results of feeds.cfm to the div. Very sweet!

<html>
<head>
<title>Ashwin's version of Todd Sharp's Feed Reader</title>
<link rel="STYLESHEET" type="text/css" href="style.css">
<InvalidTag>
</script>
</head>
<body>
<div>
<cfdiv id="feedDiv" bind="url:feeds.cfm"></div>
<div id="feedContainer"></div>
</div>
</body>
</html>

feeds.cfm:

The big change from Todd & my code here is that Ashwin built the links on the fly within the CF page and used the ColdFusion.navigate method to create the XHR call to feed.cfm and bind it to the feedContainer div. Again very sweet!

<cfxml variable="feedList">
<?xml version="1.0" encoding="UTF-8"?><feeds><feed><url>http://cfsilence.com/blog/client/rss.cfm?mode=full</url><feedTitle>Todd Sharp</feedTitle></feed><feed><url>http://feeds.feedburner.com/RaymondCamdensColdfusionBlog</url><feedTitle>Raymond Camden</feedTitle></feed><feed><url>http://www.remotesynthesis.com/blog/rss.cfm?mode=full</url><feedTitle>Brian Rinaldi</feedTitle></feed></feeds>
</cfxml>
<cfloop index="i" from="1" to="#ArrayLen(feedList.feeds.feed)#">
<cfoutput><a class='feedLink' href='javascript:ColdFusion.navigate("feed.cfm?feed=#feedList.feeds.feed[i].url.xmltext#", "feedContainer")'>#feedList.feeds.feed[i].feedTitle.xmltext#</a><br></cfoutput>
</cfloop>

feed.cfm:

<cfparam name="url.feed" default="">
<cfparam name="enclosureDir" default="#expandPath("enclosures")#">
<cfif len(url.feed)>
<cffeed action="read" source="#url.feed#" properties="feedData" query="thisFeed" enclosureDir="#enclosureDir#" ignoreEnclosureError = "true" />
<div style="margin:10px;">
<span><cfoutput><a href="#feedData.link#">#feedData.description#</a></cfoutput></span>
<cfoutput query="thisFeed">
<cfif currentRow mod 2>
<cfset bg = "CCCCDD">
<cfelse>
<cfset bg = "FFFFFF">
</cfif>
<div style="background-color:#bg#; margin: 10px 0 10px 0; border: 1px solid ##000000;">
<div style="width: 100%; margin-bottom: 10px;">
<div style="float:left;">
<a href="#rsslink#">#title#</a>
</div>
<div style="float:right; text-align: right;">
#publishedDate#
</div>
</div>
<div>
#content#
</div>
</div>
</cfoutput>
</div>
<cfelse>
</cfif>

I have to say that I truly love this version. Its very streamlined and so easy. The *only* thing that I didn't like was the inline JS being created in feeds.cfm using ColdFusion.navigate. I would prefer to have an more unobtrusive method and dynamically bind the click event after the feed authors have been returned. I'm not sure if that's possible. Ashwin?

Overall, this is a REALLY awesome implementation and shows how powerful the CF8 Ajax functionality can be.

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
todd sharp's Gravatar I actually was 90% complete on my streamlined rebuild last night and then I saw this today. Had I given the application more thought I would have hopefully ended with this streamlined end result prior to releasing it - but it was a spur of the moment lunch time slap it together kinda thing - so I didn't give it much thought. Shame on me - really there was no need for the cfsprydataset and the border layout which are what ultimately bloated the file size.

The border layout does have it's uses - which I did not highlight (such as collapsing/hiding/closing individual layoutareas, etc).

Just goes to show why this community is so good - we challenge each other and as a result we all learn. Cheers!
# Posted By todd sharp | 6/6/07 11:06 AM
Rey Bango's Gravatar @Todd:

"Just goes to show why this community is so good - we challenge each other and as a result we all learn."

Couldn't have said it better myself!
# Posted By Rey Bango | 6/6/07 11:07 AM
Dan Wilson's Gravatar That Ashwin is a smart guy, isn't he? Every time I see his name, it is attached to something cool.

Thanks Rey and Todd for starting this discussion. You are smart guys as well ;)

DW
# Posted By Dan Wilson | 6/6/07 1:24 PM
Rey Bango's Gravatar @Dan: Thanks bud. :)
# Posted By Rey Bango | 6/6/07 2:21 PM
Ashwin's Gravatar Aw shucks, Dan, you got me all red!

Thanks a lot for raising this issue, guys, it made us take a second look at our implementation, finding some places where the fat can definitely be trimmed.

Rey - the dynamic bind to the click event is, unfortunately, not possible with the current code. The way binds happen in CF is that we register for events on different controls at page load (or dynamic area load, i.e., anything with a URL bind). When an event is triggered, we go look for the current values of all controls referenced by the bind expression, and then "run" the bind based on type of the bind expression (simple, javascript, URL, CFC).

In this case, we'll need an array of controls with the same id for navigation; when the click event is propagated, the bind engine will then have to figure out which control in the array was clicked. This simply won't work with <a> tags, since there is no state on the tag to indicate that it is "selected"; what it will work with, really well, is a radio button array, though that is a decision that developers will have to take based on their needs.

I suppose this comes from being a server-based code generation solution, as opposed to a pure client-side library. We try to do all the heavy lifting, but there is a cost in terms of dictating a certain coding style, which could be good or bad, depending on what you're looking for.

This is begging to be a blog entry - coming soon, once I wipe away all these bugs I have crawling out of my ears... ;)
# Posted By Ashwin | 6/7/07 2:02 AM
BlogCFC was created by Raymond Camden. This blog is running version 5.8.001.