More Fun with AjaxCFC

Posted on Mar 26, 2006

I just finished updating the open-source list with a new feature that uses AjaxCFC to pull relevant blog posts for certain projects. This turned out to be relatively painless to implement with most of my time spent updating my form code to work with recent updates to Reactor (more on that later). Originally, I was hoping to get some fancy effects when you click the link to view posts as well (using moo.fx), but the javascript necessary seemed to have a conflict with the javascript for AjaxCFC. Anyway, for now, I will quickly review how I built the feature.The first thing I did was add a getBlogPosts function to the component that contains the functions used with AjaxCFC (for the prior code and more details on getting started with AjaxCFC refer to my prior post). The function looked like this:

<cffunction name="getBlogPosts" output="false" access="private" returntype="query">    <cfargument name="searchTerm" type="string" required="true" />    <cfargument name="currentRow" type="numeric" required="true" />        <cfset var qrySearch = "" />        <cfquery name="qrySearch" datasource="www">       SELECT   title,id,'post#arguments.currentRow#' AS divid       FROM   tblblogentries       WHERE   title LIKE <cfqueryparam cfsqltype="cf_sql_varchar" value="%#arguments.searchTerm#%" />       OR      body LIKE <cfqueryparam cfsqltype="cf_sql_varchar" value="%#arguments.searchTerm#%" />    </cfquery>    <cfreturn qrySearch /> </cffunction>

Ok, so I am not thrilled with the fact that I am doing a direct query here of the data. I had hoped to use the built in functions of BlogCFC, but since this doesn't share the application scope with my blog, I would have had to do some futzing to get all the blog initialization code working before I run the query. You will also note that AjaxCFC now uses named arguments rather than the argument array it used when I wrote my prior post. Lastly, I do something kinda funky in that I pass currentRow of the open-source list item that the function was called from, and I drop this in the query just to hold it so that it is available to the call-back function (since the call-back function can only take the result as its arguments, there wasn't another way to pass this that I could see).

The JavaScript functions look like this:

function getPosts(searchTerm,currentRow) {    DWREngine._execute(_ajaxConfig._cfscriptLocation,null,'getBlogPosts',writePosts,searchTerm,currentRow); } function writePosts(result) {    var i;    var strHTML = 'Related Blog Posts:<br />';    if (result.getRowCount()) {       for (i in result.divid) {          strHTML += '<a href\=\'../blog/index.cfm?mode=entry&entry=' + result.id[i] + '\'>' + result.title[i] + '</a><br>';       }       document.getElementById(result.divid[0]).innerHTML = strHTML;    } }

The getPosts() function takes the searchTerm (which I added a searchTerm to my open-source projects database) and the currentrow (i.e. the row of the item clicked - what I spoke about above). All this function does is the AjaxCFC call. The writePosts function loops through the query result using AjaxCFC's built in getRowCount() function. I just append the record results (id and title) into a string. I then use the divid that I appended into the query above to determine which div I am placing this content into (anyone with better javascript skills, feel free to tell me a better way to do this).

Anyway, as you can see this is pretty easy. Granted, I haven't worked out closing the posts list once you open one yet (I think in order to do this, I need to pass a couple more fields in the query in order to have the searchTerm and currentRow fields available to the writePosts() function (I will probably fix that this week). Suffice it to say, I continue to find AjaxCFC fun and easy-to-use.

Comments

Rob Gonda Brian, nice addition... let me comment on closing the post list.
I believe the action of closing it should be triggered by the getPosts() function, not by the callback. As the matter of fact, maybe you want to build in just a little more intelligence to the function; for example, always hide the current container before making the ajax call to retrieve the next list. Additionally, what if you already received a specific list, why make another call? You could easily check if the innerHTML of a container is empty or has content, if it has content just show it again, and if not, then make the ajax call.
You will be caching the results and making the app a tad more efficient.

Nice work mate! I'm glad to see how people find new uses for Ajax to improve usability and provide better experience.

Posted By Rob Gonda / Posted on 03/26/2006 at 10:17 PM


Brian Rinaldi Rob, thanks for the advice. I actually implemented some of your suggestions already and got the close function working :)

Posted By Brian Rinaldi / Posted on 03/27/2006 at 8:54 PM


Rob Gonda Nice, I see that you also added some loading msg, which is always good. I guess the caching is not a huge deal, but again, why wouldn't save some DB calls if you can.

Posted By Rob Gonda / Posted on 03/27/2006 at 9:02 PM


Brian Rinaldi It is a good idea...gimme time ;)

Posted By Brian Rinaldi / Posted on 03/27/2006 at 9:09 PM


Write your comment



(it will not be displayed)





About

My name is Brian Rinaldi and I am the Web Community Manager for Flash Platform at Adobe. I am a regular blogger, speaker and author. I also founded RIA Unleashed conference in Boston. The views expressed on this site are my own & not those of my employer.