Use Spry and ColdFusion To Create Paged Data With Additional Information Loaded Using Ajax

I needed to create a web page that would show data from a database a page of data at a time and for each item shown, have a link that would dynamically load into the page--just below the item--more details about that item. The challenge was that I could not return all the details needed from the database into one dataset because of the number of items and the size of each item. It would just take too long to get back all that XML. However, by using Spry and ColdFusion I could get the additional details for an item and load it into the page after the user clicked on a link for that item. Thus the dataset I first get when the page loads can be much smaller since it doesn't have to include all the extra details for each item.

The version of ColdFusion on our production server is still CF 7, so I could not use the new Ajax features offered by CF 8. But Spry provided everything I needed to get this to work.

To see an example webpage of what I'm trying to do go here:

/spry/fmsup/testpaging.cfm (note this example will be slightly slower since it is using an Access database for testing and not SQL Server).

If you're not familiar with using Spry to create paged datasets, see the references at the end of this article. What I want to cover here is how I got the additional data (in the above example page - the abstract for each presentation) to load when the user clicks on the View Abstract link.

The are several key concepts to make the above page work. First note the two span tags below:


<span id="link{subid}"><a href="##" onclick="javascript:getAbstract({subid}); return false">View Abstract</a></span><br />
<span class="abstractBlock" id="abstract{subid}"></span>

Both span tags get a dynamically generated unique id value. This id value will enable me to change the innerHTML value using JavaScript.

The other key concept is the ability of Spry to load a new dataset in response to an event. For example looking at the above code, when the user clicks on the View Abstract hyperlink, the JavaScript getAbstract function is called and is passed the subid value (which was provided by the dataset this region is tied to).

The getAbstract function is below:


//called when user clicks on the View Abstract link
function getAbstract( subid ) {

    //alert("submission number: " + subid) ;
    
    dsAbstract.setURL('FMSupService.cfc?method=getAbstract&subid;='+subid);
    
    //when data is returned call
//processAbstract function

    dsAbstract.addObserver( processAbstract ) ;
    
    //go to the url and get the data

    dsAbstract.loadData();
    
}//end function getAbstract

It took me awhile to figure out how to do the above. First, I change the URL value for the dsAbstract dataset. This URL will call the getAbstract method defined in the FMSupService.cfc and also pass to the method a parameter named subid (having a value of whatever was passed to the getAbstract function). Second, I register a different JavaScript function to be called when data is returned to the dsAbstract dataset. Third, I tell the dsAbrstract dataset to go and get some data.

Below is the code for the JavaScript function processAbstract. This function will be called automatically when dsAbstract receives the data back from the ColdFusion.


//called when dsAbstract has received data
function processAbstract (notificationType, notifier, data)
{
    if (notificationType != "onPostLoad")
        return;

    //Get access to all of the rows of a
    //data set with getData().


    var rows = dsAbstract.getData();
    
    //var numRows = rows.length;
    
    //alert("rows: " + numRows);
    
    //alert("data: " + rows[0].abstractText);
    
    //get the value of the subid node
//in the first row of data
    //and add it to the word abstract

    var elemID = 'abstract' + rows[0].subid;
    
    var aLinkID = 'link' + rows[0].subid;
    
    //alert ('elemID: ' + elemID);
    
    //find the HTML tag with the id value that matches
    //the value stored in elemID and set its text
    //to the value of abstractText node

    document.getElementById( elemID ).innerHTML = rows[0].abstractText;
    
    
    //create a new link that will Hide Abstract

    var changeStr = "<a href=\"##\" onclick=\"javascript:hideAbstract('" + rows[0].subid + "'); return false\">Hide Abstract</a>";
                
    document.getElementById(aLinkID).innerHTML = changeStr;
    
}//end function processAbstract



Note that the data returned by ColdFusion is XML with one node that contains child nodes named subid and abstractText. In the above function, I pull those values out of the XML that was returned. I then set the innerHTML of the HTML tag that has the id value that matches "abstract" + subid (for example abstract9015) to the abstractText value stored in dsAbstracts dataset.

I also change the innerHTML of the hyperlink so it will read "Hide Abstract" and have a different JavaScript function to execute when that link is called. The hideAbstract JavaScript function will remove the innerHTML for the abstract span tag and change the hyperlink back to "View Abstract."

Certainly all of the above would be simpler if I was able to return the abstracts along with the other information (title, authors, etc) in one dataset. But given the number of items (could be over 500) and the size of the abstracts (anywhere from 125 - 500 words) the XML returned is just too large.

If I have time I'll test returning a JSON dataset that includes all details to see if a single JSON dataset would work.

References:

  1. Spry Framework for Ajax
  2. Use Spry to Page Forward and Backward Through Records - A Simple Tutorial
  3. Working With Spry XML Data Sets
  4. Spry Paged Data and Filtering

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
BlogCFC was created by Raymond Camden. This blog is running version 5.9.1.002. Contact Blog Owner