ColdFusion provides support for mixing native ColdFusion elements and Spry elements in a single application.
To bind to a Spry data set, specify the data set name followed by the path to the specific element that you bind to, by using standard Spry path syntax. For example, if dsFilters is a Spry data set with a name column, the {dsFilters.name} bind parameter binds to the value of the current row's name column. The bind parameter cannot specify an event; the bind expression is re-evaluated each time the selected row in the data set changes. The following example shows the bind syntax:
<cfinput name="Input1" type="text" bind="CfC:DataManager.getInData(filter={dsFilters.name})
Spry.Data.XMLDataSet("MyAppMgr.cfc?method=getFilter&filter="scores", "filters/filter");
The following example shows a cfsprydataset tag that creates a Spry XML data set named dsProducts by calling the getData.getProductDetails function and passing it the value of the selected name in a cfgrid control. The data set updates each time the name value changes.
<cfsprydataset name="dsProducts" type="xml" bind="CFC:getData.getProductDetails(prodname={myform:mygrid.name})" xpath="products/product" options="{method: 'POST'}" onBindError="errorHandler">
ColdFusion includes the complete Spry 1.5 framework release in web_root/CFIDE/scripts/ajax/spry directory. For more information, see the Adobe Labs Spry framework pages. For more information, see the cfsprydataset tag in the CFML Reference.
This example has the following behavior:
The example lets a user select the genre of books to display: all books, fiction, or nonfiction from a Spry list box populated from the XML file. The selected genre determines the information displayed by a cfgrid control, and a text input control shows the selected genre. The selected item in the cfgrid control determines the information that is displayed in a second Spry dynamic region.
The application consists of the following files:
For this example to display images, you must also create an images subdirectory of your application directory that contains images with the names specified by the BOOKIMAGE column of the cfbookclub database BOOKS table.
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:spry="http://ns.adobe.com/spry"> <head> <!--- The screen.css style sheet is provided in the Spry distribution. ---> <link href="screen.css" rel="stylesheet" type="text/css" media="all"/> <!--- Include the XPath and Spry JavaScript files. ---> <script type="text/javascript" src="/CFIDE/scripts/ajax/spry/includes/xpath.js"></script> <script type="text/javascript" src="/CFIDE/scripts/ajax/spry/includes/SpryData.js"></script> <!--- Create the dsFilters Spry XML data set used to populate the FiltersList dynamic region that lists the filters. Call the GridDataManager CFC getFilter method directly from a Spry XMLDataSet function because no binding is needed. ---> <script> var dsFilters = new Spry.Data.XMLDataSet("GridDataManager.cfc?method=getFilter", "filters/filter"); </script> <!--- Use a cfsprydataset tag with binding to generate a dsProduct Spry data set with details about the book grid selection. ---> <cfsprydataset name="dsProduct" type="xml" bind="CFC:GridDataManager.getProductDetails(prodname={bookform:bookgrid.TITLE})" xpath="products/product" options="{method: 'POST'}" onBindError="errorHandler"> <!--- Function to handle bind errors. ---> <script language="javascript"> errorHandler = function(code,msg){ alert("Error w/bind occurred. See details below:\n\n" + "Error Code: " + code + "\n" + "Error Message: " + msg); } </script> <!--- Specify the size of the FiltersList Spry dynamic region. By default it would be unnecessarily large. ---> <style type="text/css"> <!-- #FiltersList { height:100px; width: 150px; } --> </style> </head> <body> <!--- A Spry dynamic region containing repeated ListBoxItem controls. Each item specifies a filter to use in filling the book list grid. The items are populated by the data from the CFC getFilter method. ---> <div id="FiltersList" spry:region="dsFilters" class="SpryHiddenRegion"> <div spry:repeat="dsFilters" class="ListBoxItemGroup"> <div class="ListBoxItem" onclick="dsFilters.setCurrentRow('{dsFilters::ds_RowID}');" spry:selectgroup="feedsList" spry:select="SelectedListBoxItem" spry:hover="ListBoxItemHover"> {dsFilters::description} </div> </div> </div> <!--- A ColdFusion form with the book list data grid. ---> <cfform name="bookform"> <!--- Create a book list grid. Users select the book for which to get details from this grid. Populate it with the results of the CFC getData method. Pass the method the value of the name field of the selected item in the dsfilters Spry dynamic region. ---> <cfgrid name="bookgrid" format="html" bind="CfC:GridDataManager.getData(page={cfgridpage}, pageSize={cfgridpagesize},sortCol={cfgridsortcolumn}, sortDir={cfgridsortdirection},filter={dsFilters.name})" selectMode="browse" width=400 delete="true" pageSize=7> <cfgridcolumn name="TITLE" header="Name" width=200> <cfgridcolumn name="GENRE" header="Type" width=200> </cfgrid><br /> <!--- Show the value of the name field of the selected item in the Spry dynamic region. ---> <cfinput name="filter" bind="{dsFilters.name}"> </cfform> <hr> <!--- A Spry dynamic region that uses the dsProduct data set to display information on the selected product. ---> <div id="RSSResultsList" spry:detailregion="dsProduct" class="SpryHiddenRegion"> <strong>{name}</strong><br> <img src="images/{bookimage}" alt="product box shot" width="238" height="130"/> <div>{desc}</div> </div> <hr> </body> </html>
<cfcomponent name="GridDataManager"> <!--- The getFilter function gets the filter XML to populate the dsFilters Spry data set. It specifies returnFormat=plain to send XML text. ---> <cffunction name="getFilter" access="remote" output="false" returnFormat="plain"> <cffile action="read" file="#ExpandPath('.')#\Filters.xml" variable="filtersxml"> <cfcontent type="text/xml" reset="yes"> <cfreturn filtersxml> </cffunction> <!--- The getData function returns books that match the specified genre, or all books if there is no genre. ---> <cffunction name="getData" access="remote" output="false"> <cfargument name="page" required="yes"> <cfargument name="pageSize" required="yes"> <cfargument name="sortCol" required="yes"> <cfargument name="sortDir" required="yes"> <cfargument name="filter" required="no"> <cfquery name="books" datasource="cfbookclub"> select TITLE, GENRE from BOOKS <cfif isDefined("arguments.filter") AND arguments.filter NEQ ""> where GENRE = '#arguments.filter#' </cfif> <cfif arguments.sortCol NEQ "" AND arguments.sortDir NEQ ""> order by #arguments.sortCol# #arguments.sortDir# <cfelse> order by TITLE ASC </cfif> </cfquery> <!--- Return the data only for the current page. ---> <cfreturn QueryConvertForGrid(books, arguments.page, arguments.pageSize)> </cffunction> <!--- The getProductDetails gets data for a single book and converts it to XML for use in the dsProduct Spry data set. ---> <cffunction name="getProductDetails" access="remote" output="false"> <cfargument name="prodname" default="The Road"> <!--- Get the information about the book from the database. ---> <cfquery name="bookDetails" datasource="cfbookclub"> select TITLE, GENRE, BOOKIMAGE, BOOKDESCRIPTION from BOOKS where TITLE = '#arguments.prodname#' </cfquery> <!--- Convert the query results to XML. ---> <cfoutput> <cfxml variable="BookDetailsXML" > <?xml version="1.0" encoding="iso-8859-1"?> <products> <product> <name>#BookDetails.TITLE#</name> <category>#BookDetails.GENRE#</category> <bookimage>#BookDetails.BOOKIMAGE#</bookimage> <desc>#BookDetails.BOOKDESCRIPTION#</desc> </product> </products> </cfxml> </cfoutput> <!--- Convert the XML object to an XML string. ---> <cfset xmldata = xmlparse(BookDetailsXML)> <cfcontent type="text/xml" reset="yes"> <cfreturn xmldata> </cffunction> </cfcomponent>
<?xml version="1.0" encoding="iso-8859-1"?> <filters> <filter> <filterid>1</filterid> <name></name> <description>No Filter</description> </filter> <filter> <filterid>2</filterid> <name>Fiction</name> <description>Look for Fiction</description> </filter> <filter> <filterid>3</filterid> <name>Non-fiction</name> <description>Look for Nonfiction</description> </filter> </filters>