<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>rabidGadfly &#187; ajax</title>
	<atom:link href="http://rabidgadfly.com/category/ajax/feed/" rel="self" type="application/rss+xml" />
	<link>http://rabidgadfly.com</link>
	<description>Simple Solutions to Nagging Coding Problems</description>
	<lastBuildDate>Wed, 19 Oct 2011 13:43:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Using CFAjaxProxy in a Shared Hosting Environment</title>
		<link>http://rabidgadfly.com/2008/09/using-cfajaxproxy-in-a-shared-hosting-environment/</link>
		<comments>http://rabidgadfly.com/2008/09/using-cfajaxproxy-in-a-shared-hosting-environment/#comments</comments>
		<pubDate>Wed, 10 Sep 2008 19:43:47 +0000</pubDate>
		<dc:creator>rabidgadfly</dc:creator>
				<category><![CDATA[ajax]]></category>
		<category><![CDATA[coldFusion]]></category>
		<category><![CDATA[cfajax.js]]></category>
		<category><![CDATA[cfajaxproxy]]></category>
		<category><![CDATA[cfide]]></category>
		<category><![CDATA[cfmessage.js]]></category>
		<category><![CDATA[shared hosting]]></category>

		<guid isPermaLink="false">http://www.rabidgadfly.com/?p=69</guid>
		<description><![CDATA[As I mentioned in my last post (Drag and Drop Sorting with CFAjaxProxy and Script.aculo.us) I&#8217;ve started to use CFAjaxProxy. It&#8217;s been very easy to integrate and I had no problems at all on my local machine. However, after posting my work to a live site my AJAX functionality ceased working. Thanks to Firebug, I [...]]]></description>
			<content:encoded><![CDATA[<p>As I mentioned in my last post (<a href="http://www.rabidgadfly.com/?p=68" alt="Read my post! (But finish this one first)">Drag and Drop Sorting with CFAjaxProxy and Script.aculo.us</a>) I&#8217;ve started to use CFAjaxProxy. It&#8217;s been very easy to integrate and I had no problems at all on my local machine. However, after posting my work to a live site my AJAX functionality ceased working.</p>
<p>Thanks to <a href="https://addons.mozilla.org/en-US/firefox/addon/1843" alt="Get Firebug for Firefox!">Firebug</a>, I was able to track down the issue pretty quickly. The cfajax.js and cfmessage.js libraries were failing to load. These files are located in subfolders under the CFIDE folder.</p>
<p>For those unfamiliar with the CFIDE folder, it contains central and core coldfusion files, custom tags, libraries and the ColdFusion administrator. The reason I wasn&#8217;t having the problem locally was because I wasn&#8217;t in a shared hosting environment so CFIDE was right where ColdFusion expected it to be.</p>
<p>In a shared hosting environment, however, ColdFusion looks for CFIDE in the root of the current domain. So, rather than looking in the web server root, it looks in the domain root. For example, if the site I&#8217;m working on is mysite.com, ColdFusion will look for CIDE in http://www.mysite.com/CFIDE/.</p>
<p>While I could make a virtual directory mapping to the existing CFIDE folder, I didn&#8217;t want to expose the ColdFusion Administrator. Instead, I created a new CFIDE folder and copied only the SCRIPTS subfolder into it. I then created a CFIDE virtual directory within the domain which pointed to the new CFIDE folder.</p>
<p>I know many developers have experienced a similar issue with CFFORM, however, that issue can be surmounted with the use of the <a href="http://tutorial157.easycfm.com/" alt="using CFFORM in a hosted environment">scriptsrc parameter</a> which isn&#8217;t available for CFAjaxProxy.</p>
<p>Admittedly, this solution feels a bit lame, but I&#8217;m unaware of any other way around it. If you know of a better way, please leave a comment!</p>
<p>-rG</p>
]]></content:encoded>
			<wfw:commentRss>http://rabidgadfly.com/2008/09/using-cfajaxproxy-in-a-shared-hosting-environment/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Drag and Drop Sorting with CFAjaxProxy and Script.aculo.us</title>
		<link>http://rabidgadfly.com/2008/08/drag-and-drop-sorting-with-cfajaxproxy-and-scriptaculous/</link>
		<comments>http://rabidgadfly.com/2008/08/drag-and-drop-sorting-with-cfajaxproxy-and-scriptaculous/#comments</comments>
		<pubDate>Mon, 25 Aug 2008 03:39:52 +0000</pubDate>
		<dc:creator>rabidgadfly</dc:creator>
				<category><![CDATA[ajax]]></category>
		<category><![CDATA[coldFusion]]></category>
		<category><![CDATA[script.aculo.us]]></category>
		<category><![CDATA[cfajaxproxy]]></category>
		<category><![CDATA[drag and drop]]></category>
		<category><![CDATA[sort]]></category>

		<guid isPermaLink="false">http://www.rabidgadfly.com/?p=68</guid>
		<description><![CDATA[I made a video player recently containing a list of videos. My client requested the ability to put them in a custom order. It didn&#8217;t take much research to find the functionality in the Script.aculo.us library. The question was, how do I implement it with ColdFusion? I knew I would need AJAX functionality and, up [...]]]></description>
			<content:encoded><![CDATA[<p>I made a video player recently containing a list of videos. My client requested the ability to put them in a custom order. It didn&#8217;t take much research to find the functionality in the <a href="http://script.aculo.us/">Script.aculo.us</a> library. The question was, how do I implement it with ColdFusion?</p>
<p>I knew I would need AJAX functionality and, up to this point, I had always used Rob Gonda&#8217;s AjaxCFC. With the release of ColdFusion 8, however, Adobe introduced <a href="http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=Tags_a-b_3.html">CFAjaxProxy</a>. I&#8217;d been looking for an opportunity to give it a try and this turned out to be a perfect fit.</p>
<p>Jake Munson of <a href="http://techfeed.net/blog/">Yacoblog</a> posted a <a href="http://techfeed.net/blog/index.cfm/2007/6/18/ColdFusion-8-CFAjaxProxy">great introduction to using CFAjaxProxy</a>. Simple and straight to the point. I had it working in no time.</p>
<p>My next stop was a <a href="http://www.lynchconsulting.com.au/blog/index.cfm/2007/7/15/JavaScript-Drag--Drop">post by Mohammed Irfaan</a> over at the <a href="http://www.lynchconsulting.com.au/blog/">Lynch Consulting Blog</a> which discusses a technique for using ColdFusion to update an underlying table after using Script.aculo.us&#8217;s Drag and Drop functionality.</p>
<p>Here&#8217;s how I put it all together:<br />
<span id="more-68"></span><br />
First, I created a table named videocenter to hold my video records. It looks something like this:<br />
video_uuid &#8211; Unique identifier for each video record<br />
video_title &#8211; Title for the video record<br />
sort_order &#8211; Integer reflecting the order in which the video should be displayed.</p>
<p>Next, I wrote my sortvideos CFC which will loop through the list of videos that my page will send to it, and update the sort_order column to reflect the order in which the video are currently displayed on the screen (more about that later):</p>
<pre><code>
<cfcomponent>
<cffunction name="updateVideoSort" access="remote" returntype="boolean">
	<cfargument name="sortStruct" type="any" required="yes">
	<cfset var q="" />
	<cfset var i=0 />
	<cfloop from="1" to="#ListLen(arguments.sortStruct)#" index="i">
	   <cfquery name="q" datasource="#application.dsn#">
	      UPDATE	videocenter
	      SET 		sort_order = <cfqueryparam value="#i#" cfsqltype="cf_sql_integer">
	      WHERE 	video_uuid = <cfqueryparam value="#trim(listGetAt(arguments.sortStruct, i))#" cfsqltype="cf_sql_varchar" />
	   </cfquery>
	</cfloop>
	<cfreturn true>
</cffunction>
</cfcomponent>
</code></pre>
<p>After downloading and installing the <a href="http://script.aculo.us/">Script.aculo.us</a> JavaScript library, I began to build my page.</p>
<p>I started off by defining the Ajax proxy. This line defines my ColdFusion component (sortvideos) and the JavaScript proxy class that represents the CFC (respond):</p>
<pre><code>
<cfajaxproxy cfc="sortvideos" jsclassname="respond">
</code></pre>
<p>I then included the necessary Script.aculo.us files and the JavaScript function that will call the Ajax method within my ColdFusion component. Note that you may have to alter the path to the JavaScript files depending on where yours are stored:</p>
<pre><code>
<script language="JavaScript" src="js/scriptaculous/lib/prototype.js"></script>
<script language="JavaScript" src="js/scriptaculous/src/scriptaculous.js"></script>

<script type="text/javascript">
function resort() {
	var r= new respond();
	var orderList = '';
	//call the echo function from the CFC
	orderedNodes = document.getElementById("sortable_list").getElementsByTagName("li");
	for (var i=0;i < orderedNodes.length;i++) {
		orderList += orderedNodes[i].getAttribute('recordid') + ', ';
	}
	r.updateVideoSort(orderList);
  }
</script>
</code></pre>
<p>When called, orderedNodes will become an array of the LI elements within the "sortable_list" UL element defined below. The elements in the array will be in the order in which the list appears on the page. This is the list that gets sent to the updateVideoSort method within my sortvideos CFC above.</p>
<p>Next, I loop through my video records and display the videos in an unordered list. I add an ID to the UL named "sortable_list" and I add a custom attribute to each LI element (recordid) containing video_uuid from my videos table. After that, I place a submit button that will call my resort() function when clicked.</p>
<pre><code>
<cfset qvideos = videosService.getVideos() />
<ul id="sortable_list" style="cursor: move; list-style:none;">
<cfoutput query="qvideos">
<li recordid="#video_uuid#">#video_title#</li>

</cfoutput>
</ul>
<input type="button" onclick="resort();" value="Submit new order" />
</code></pre>
<p>Finally, a last bit of required JavaScript to make the Script.aculo.us magic happen. Note that "sortable_list" is the id I gave to my UL element above.<br />
<script language="JavaScript">
	Sortable.create("sortable_list");
</script></p>
<p>Now I have a list of videos from my videocenter table which can be ordered using drag and drop functionality a la Netflix.</p>
<p>-rG</p>
]]></content:encoded>
			<wfw:commentRss>http://rabidgadfly.com/2008/08/drag-and-drop-sorting-with-cfajaxproxy-and-scriptaculous/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Using Spry to Auto-select a Form Value</title>
		<link>http://rabidgadfly.com/2007/03/using-spry-to-auto-select-a-form-value/</link>
		<comments>http://rabidgadfly.com/2007/03/using-spry-to-auto-select-a-form-value/#comments</comments>
		<pubDate>Thu, 01 Mar 2007 14:28:28 +0000</pubDate>
		<dc:creator>rabidgadfly</dc:creator>
				<category><![CDATA[ajax]]></category>
		<category><![CDATA[coldFusion]]></category>
		<category><![CDATA[spry]]></category>

		<guid isPermaLink="false">http://www.rabidgadfly.com/?p=27</guid>
		<description><![CDATA[So far I&#8217;ve covered how to use multi-related selects in Spry and how to dynamically update the select list upon a database update. That&#8217;s good enough for a simple &#8216;add record&#8217; form but when it comes to an editing an existing record I want to be able to have the saved column&#8217;s value automatically selected [...]]]></description>
			<content:encoded><![CDATA[<p>So far I&#8217;ve covered how to use <a href="http://www.rabidgadfly.com/?p=25">multi-related selects</a> in Spry and how to <a href="http://www.rabidgadfly.com/?p=26">dynamically update the select</a> list upon a database update. That&#8217;s good enough for a simple &#8216;add record&#8217; form but when it comes to an editing an existing record I want to be able to have the saved column&#8217;s value automatically selected in its select box.</p>
<p>Adobe&#8217;s samples didn&#8217;t seem to cover this scenario so it became a matter of trial and error, and a lot of wading through documentation. In the end, however, it turned out to be a matter of changing only a few lines of code.<br />
<span id="more-27"></span><br />
First, let&#8217;s revisit my previous select code:</p>
<pre>
<code>
<select spry:repeatchildren="dsBrands" name="brandID"
onchange="document.forms[0].subbrandselect.disabled = true;
dsBrands.setCurrentRowNumber(this.selectedIndex);">
<option spry:if="<span style='color:red;'>{ds_RowNumber} == {ds_CurrentRowNumber}</span>" value="{brandID}" selected="selected">{brandNAME}</option>
<option spry:if="<span style='color:red;'>{ds_RowNumber} != {ds_CurrentRowNumber}</span>" value="{brandID}">{brandNAME}</option>
</select>

</code>
</pre>
<p>The portion we need to look at in particular is in red. ds_RowNumber reflects the position of the row currently being evaluated. ds_CurrentRowNumber is the row number of the &#8220;current row&#8221; of the data set. This works if I don&#8217;t need a specific value to be selected, but it does absolutely nothing for me if I want the saved value to be selected in the list when editing.</p>
<p>What I need is a way to check whether a brandID in the dsBrands dataset is equal to the brand ID of the record I&#8217;m editing. So, the first thing I need to know is how to refer to the value of the dataset&#8217;s current brand_id. This is done by enclosing the column name in single quotes, like this: &#8216;{brandID}&#8217;.</p>
<p>Now I can compare that value to the brand ID of the record I&#8217;m editing. For example, if the query object of the current record that I&#8217;m editing is named qEditProduct and the column that holds the brand id in qEditProduct is called brand_id, I would refer to it like this: #qEditProduct.brand_id# .</p>
<p>Compare one to the other and I have my new SELECT definition:</p>
<pre>
<code>
<select spry:repeatchildren="dsBrands" name="brandID"
onchange="document.forms[0].subbrandselect.disabled = true;
dsBrands.setCurrentRowNumber(this.selectedIndex);">
<option spry:if="<span style='color:red;'>'{brandID}' == <cfoutput>#qEditProduct.brand_id#</cfoutput></span>" value="{brandID}" selected="selected">{brandNAME}</option>
<option spry:if="<span style='color:red;'>'{brandID}' != <cfoutput>#qEditProduct.brand_id#</cfoutput></span>" value="{brandID}">{brandNAME}</option>
</select>

</code>
</pre>
<p>Now, if the value of brand ID in my select matches the value of the brand ID in the record I&#8217;m editing it will be pre-selected in the list.</p>
<p>To take this a step further, my original example was on multi-related selects, meaning I had subbrand select that was related to the value in the brand select. That being the case, I first have to make the same change to the subbrand select definition resulting in the following code:</p>
<pre>
<code>
<select spry:repeatchildren="dsSubbrands" name="subbrandselect" >
<option spry:if="'<span style='color:red;'>{brandID}' == <cfoutput>#qEditProduct.brand_id#</cfoutput></span>" value="{subbrandNAME}" selected="selected">{subbrandNAME}</option>
<option spry:if="'<span style='color:red;'>{brandID}' == <cfoutput>#qEditProduct.brand_id#</cfoutput></span>" value="{subbrandNAME}">{subbrandNAME}</option>
</select>

</code>
</pre>
<p>Then, I also need to modify my dataset definition. Initially, dsSubbrands definition was based on the value of the brand select. The subbrands changed when the brand changed. If we&#8217;re editing, however, we want our subbrand to depend on the value stored in the current record rather than being related to the brand select. My original dsSubbrands dataset definition looked like this:</p>
<pre>
<code>
var dsSubbrands = new Spry.Data.XMLDataSet("subbrands.cfm?brandID=<span style='color:red;'>{dsBrands::brandID}</span>","subbrands/subbrand");
</code>
</pre>
<p>{dsBrands::brandID} is my reference to the selected item in the brands select. I need to change that so it now refers to the current record in my qEditProduct query:</p>
<pre>
<code>
var dsSubbrands = new Spry.Data.XMLDataSet("subbrands.cfm?brandID=<span style='color:red;'><cfoutput>#qEditProduct.brand_id#</cfoutput></span>","subbrands/subbrand");
</code>
</pre>
<p>Now when I edit a record, the record values will be pre-selected in both the brand and subbrand dropdown. You can use the original code for &#8216;add record&#8217; forms or, for more condensed code, combine them both into a conditional check based on whether the user is adding or editing a record.</p>
<p>-rG</p>
]]></content:encoded>
			<wfw:commentRss>http://rabidgadfly.com/2007/03/using-spry-to-auto-select-a-form-value/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Updating a Spry Dataset from a Popup</title>
		<link>http://rabidgadfly.com/2007/02/updating-a-spry-dataset-from-a-popup/</link>
		<comments>http://rabidgadfly.com/2007/02/updating-a-spry-dataset-from-a-popup/#comments</comments>
		<pubDate>Tue, 27 Feb 2007 15:21:22 +0000</pubDate>
		<dc:creator>rabidgadfly</dc:creator>
				<category><![CDATA[ajax]]></category>
		<category><![CDATA[coldFusion]]></category>
		<category><![CDATA[spry]]></category>

		<guid isPermaLink="false">http://www.rabidgadfly.com/?p=26</guid>
		<description><![CDATA[Last week I posted a method of using multi-related selects with Spry and ColdFusion. In my example I updated a subbrands dataset when a brand select was updated. I implemented a similar process at work and decided that it would be nice to offer the option of adding new subbrands from the data entry form. [...]]]></description>
			<content:encoded><![CDATA[<p>Last week I posted a <a href="http://www.rabidgadfly.com/?p=25">method</a> of using multi-related selects with Spry and ColdFusion. In my example I updated a subbrands dataset when a brand select was updated. I implemented a similar process at work and decided that it would be nice to offer the option of adding new subbrands from the data entry form. To do so, I placed an &#8216;add&#8217; button next to the subbrands select which opens a popup where the user can add a new subbrand. Then came the question, how do I update the dataset on the parent window once the new subbrand is added.</p>
<p>It actually ended up being quite easy.<br />
<span id="more-26"></span><br />
The original code for defining the Spry datasets looked like this:</p>
<pre>
<code>
<script type="text/javascript">
var dsBrands = new Spry.Data.XMLDataSet("brands.cfm","brands/brand");
var dsSubbrands = new Spry.Data.XMLDataSet("subbrands.cfm?brandID={dsBrands::brandID}","subbrands/subbrand");
</script>
</code>
</pre>
<p> Once the subbrands for a particular brand were read in, however, they would no longer updated. To force an update I just had to add a little code and a function to the subbrands definition:</p>
<pre>
<code>
var dsSubbrands = new Spry.Data.XMLDataSet("xmlSubbrands.cfm?brand_id={dsBrands::brand_id}",
"subbrands/subbrand"<span style='color:red;'>,{useCache:false});
function refreshSubbrands()  {dsSubbrands.url="xmlSubbrands.cfm?brand_id={dsBrands::brand_id}&#038;cachebuster=<cfoutput>#Now()#</cfoutput>";
dsSubbrands.loadData();}</span>
</code>
</pre>
<p>The first thing I do is disable the cache. Then I define a function that will redefine and reload the dsSubbrands dataset. I added in the date and time to the URL to further prevent XML caching. That&#8217;s all the code required to update the select list.</p>
<p>The only thing left to do from here is to get the popup to execute the function. This is accomplished by adding the following code after the insert is completed:</p>
<pre>
<code>
<script>
	if(window.opener) {
		window.opener.refreshSubbrands();
	}
</script>
</code>
</pre>
<p>window.opener is a reference to the window that opened the current window. The reason I check whether the referencing page exists is so that the add subbrand form can also be used as a normal page outside of the form that calls it as a popup. refreshSubbrands is the function I created to reload the subbrands select. In this way, the select list is updated as soon as the update is completed. No refresh is necessary, even if the parent brand is already selected.</p>
<blockquote><p><strong>Credit Where Credit Is Due</strong><br />
I found the guts of this technique on <a href="http://www.infoaccelerator.net/index.cfm/2007/1/29/index.cfm?event=showHome">Andrew Powell&#8217;s ColdFusion, Mach-II, Flex,</a><a href="http://www.usingdrugswisely.com"> and Spry Blog</a> where he has a <a href="http://www.infoaccelerator.net/index.cfm/2007/1/29/index.cfm?event=showEntry&#038;entryId=D51598A5-ECD3-ED82-F0985C3541DF7990">great example</a> demonstrating how to page through a set of data in 10 record increments.</p></blockquote>
<p>-rG</p>
]]></content:encoded>
			<wfw:commentRss>http://rabidgadfly.com/2007/02/updating-a-spry-dataset-from-a-popup/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Experimenting with Multi-related Selects using Spry</title>
		<link>http://rabidgadfly.com/2007/02/experimenting-with-multi-related-selects-using-spry/</link>
		<comments>http://rabidgadfly.com/2007/02/experimenting-with-multi-related-selects-using-spry/#comments</comments>
		<pubDate>Thu, 22 Feb 2007 14:17:25 +0000</pubDate>
		<dc:creator>rabidgadfly</dc:creator>
				<category><![CDATA[ajax]]></category>
		<category><![CDATA[coldFusion]]></category>
		<category><![CDATA[spry]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://www.rabidgadfly.com/?p=25</guid>
		<description><![CDATA[I recently found myself in need of a multi-related select solution and decided to give Adobe&#8217;s new Spry framework a shot. The first thing I noticed was that, still being in development, there isn&#8217;t much Spry documentation. In lieu of docs Adobe provides several samples which, though useful, did not provide the solution I was [...]]]></description>
			<content:encoded><![CDATA[<p>I recently found myself in need of a multi-related select solution and decided to give <a href="http://labs.adobe.com/technologies/spry/" alt="Adobe Spry">Adobe&#8217;s new Spry framework</a> a shot.</p>
<p>The first thing I noticed was that, still being in development, there isn&#8217;t much Spry documentation. In lieu of docs Adobe provides several samples which, though useful, did not provide the solution I was looking for. My goal is to have two select boxes, each populated by separate but related datasets. In the example I use below, my datasets are brands and subbrands. The subbrands dataset contains a brandID column which is related to the brandID column in the brands dataset. Read on to see how I did it and feel free to leave a comment telling me how I should have done it <img src='http://rabidgadfly.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  .<br />
<span id="more-25"></span></p>
<p>First, I set up my two datasets in a component named datasets.cfc.:</p>
<pre>
<code>
<cfcomponent>
   <cffunction name="getBrands" output="no" access="public" returntype="query">
		<cfset tbl = queryNew("brandID,brand")>
		<cfset queryAddRow(tbl)>
		<cfset querySetCell(tbl, "brandID", 1)>
		<cfset querySetCell(tbl, "brand", "GI Joe")>
		<cfset queryAddRow(tbl)>
		<cfset querySetCell(tbl, "brandID", 2)>
		<cfset querySetCell(tbl, "brand", "Star Wars")>
		<cfset queryAddRow(tbl)>
		<cfset querySetCell(tbl, "brandID", 3)>
		<cfset querySetCell(tbl, "brand", "Transformers")>

      <cfreturn tbl />

   </cffunction>

     <cffunction name="getSubbrands" output="no" access="public" returntype="query">
	 	<cfargument name="brandID" type="numeric" required="yes">
		<cfset tbl = queryNew("brandID,subbrand")>
		<cfset queryAddRow(tbl)>
		<cfset querySetCell(tbl, "brandID", 1)>
		<cfset querySetCell(tbl, "subbrand", "Army Rangers")>
		<cfset queryAddRow(tbl)>
		<cfset querySetCell(tbl, "brandID", 1)>
		<cfset querySetCell(tbl, "subbrand", "Navy Seals")>
		<cfset queryAddRow(tbl)>
		<cfset querySetCell(tbl, "brandID", 1)>
		<cfset querySetCell(tbl, "subbrand", "Sigma 6")>
		<cfset queryAddRow(tbl)>
		<cfset querySetCell(tbl, "brandID", 2)>
		<cfset querySetCell(tbl, "subbrand", "Clone Wars")>
		<cfset queryAddRow(tbl)>
		<cfset querySetCell(tbl, "brandID", 2)>
		<cfset querySetCell(tbl, "subbrand", "Jedi Force")>
		<cfset queryAddRow(tbl)>
		<cfset querySetCell(tbl, "brandID", 2)>
		<cfset querySetCell(tbl, "subbrand", "Original Trilogy")>
		<cfset queryAddRow(tbl)>
		<cfset querySetCell(tbl, "brandID", 3)>
		<cfset querySetCell(tbl, "subbrand", "Beast Wars")>
		<cfset queryAddRow(tbl)>
		<cfset querySetCell(tbl, "brandID", 3)>
		<cfset querySetCell(tbl, "subbrand", "Cybertron")>
		<cfset queryAddRow(tbl)>
		<cfset querySetCell(tbl, "brandID", 3)>
		<cfset querySetCell(tbl, "subbrand", "Decepticon")>

		<cfquery name="ds" datasource="query">
			select *
			from tbl
			where brandID = #arguments.brandID#
		</cfquery>

      <cfreturn ds />

   </cffunction>

</cfcomponent>
</code>
</pre>
<p>Next, I created two ColdFusion pages, brands.cfm and subbrands.cfm, that output XML. These will be used as the sources for my selects. The brands.cfm page will output all brands. The subbrands.cfm will expect a URL variable named brandID and will output only the subbrands with that brand ID.</p>
<p>A small diversion: One reason I used external pages to output my XML was that it allowed me to easily insert a new row at the beginning of the dataset. I wanted an additional option with a value of 0 which gets submitted if no brand is selected, In the select box this value is represented by the text: &#8216;Please select a brand&#8217;.</p>
<p>Here are the pages that output XML:</p>
<p>brands.cfm</p>
<pre>
<code>
<cfsetting enablecfoutputonly="no">
<cfset objDatasets = createObject("component","cfc.datasets") />
<cfset qGetBrands = objDatasets.getBrands() />
<cfsavecontent variable="thisXML">
<cfoutput>
<brands>
	<brand>
		<brandID>0</brandID>
		<brandNAME>Select a brand</brandNAME>
	</brand>
	<cfloop query="qGetBrands">
	<brand>
		<brandID>#xmlFormat(brandID)#</brandID>
		<brandNAME>#xmlFormat(brand)#</brandNAME>
	</brand>
	</cfloop>
</brands>
</cfoutput>
</cfsavecontent>
<!--- output XML --->
<cfcontent type="text/xml" reset="true">
<cfoutput>#thisXML#</cfoutput>
<cfabort>
</code>
</pre>
<p>subbrands.cfm</p>
<pre>
<code>
<cfsetting enablecfoutputonly="no">
<cfparam name="url.brandID" default=0>
<cfset objDatasets = createObject("component","datasets") />
<cfset qGetSubbrands = objDatasets.getSubbrands(url.brandID) />

<cfsavecontent variable="thisXML">
<cfoutput>
<subbrands>
	<cfif qGetSubbrands.recordcount eq 0>
		<subbrand>
			<subbrand_id>0</subbrand_id>
			<subbrand_name>No subbrands available</subbrand_name>
		</subbrand>
	<cfelseif qGetSubbrands.recordcount gt 1>
		<subbrand>
			<subbrand_id>0</subbrand_id>
			<subbrand_name>Select a subbrand</subbrand_name>
		</subbrand>
	</cfif>
	<cfloop query="qGetSubbrands">
	<subbrand>
		<subbrand_id>#xmlFormat(subbrand_id)#</subbrand_id>
		<subbrand_name>#xmlFormat(subbrand_name)#</subbrand_name>
	</subbrand>
	</cfloop>
</subbrands>
</cfoutput>

</cfsavecontent>

<cfcontent type="text/xml" reset="true">
<cfoutput>#thisXML#</cfoutput>
<cfabort>
</code>
</pre>
<p>Now the meat of the main page which holds the selects. The first thing I do is load the <a href="http://www.macromedia.com/go/labs_spry_download">Spry js files</a>:</p>
<pre><code>
<script language="JavaScript" type="text/javascript" xsrc="js/spry/xpath.js"></script>
<script language="JavaScript" type="text/javascript" xsrc="js/spry/SpryData.js"></script>
</code></pre>
<p>Next, I define my XML datasets by pointing the js variables to the appropriate XML-generating pages. Notice that my dsSubbrands dataset passes the current value of brandID to the subbrands page. The second parameter in the method calls (&#8220;brands/brand&#8221; and &#8220;subbrands/subbrand&#8221;) refer to the XML node names leading to the records.</p>
<pre><code>
<script type="text/javascript">
var dsBrands = new Spry.Data.XMLDataSet("brands.cfm","brands/brand");
var dsSubbrands = new Spry.Data.XMLDataSet("subbrands.cfm?brandID={dsBrands::brandID}","subbrands/subbrand");
</script>
</code></pre>
<p>And finally, I place the selects by providing repeatingchildren with my dataset names and using the brace format to provide the column names within the source xml ({brandID}, {brandNAME} and {subbrandNAME}):</p>
<pre><code>
<form name="frmSpry" action="#CGI.SCRIPT_NAME#">
<cfoutput>
<table border="0">
<tr>
<td>Brand:</td>
<td><span spry:region="dsBrands" id="brandSelector">
<select spry:repeatchildren="dsBrands" name="brandID"
onchange="document.forms[0].subbrandselect.disabled = true;
dsBrands.setCurrentRowNumber(this.selectedIndex);">
<option spry:if="{ds_RowNumber} == {ds_CurrentRowNumber}" value="{brandID}" selected="selected">{brandNAME}</option>
<option spry:if="{ds_RowNumber} != {ds_CurrentRowNumber}" value="{brandID}">{brandNAME}</option>
</select>

</span>
		</td>
</tr>
<tr>
<td>Subbrand:</td>
<td><span spry:region="dsSubbrands" id="subbrandSelector">
<select spry:repeatchildren="dsSubbrands" name="subbrandselect" >
<option spry:if="{ds_RowNumber} == {ds_CurrentRowNumber}" value="{subbrandNAME}" selected="selected">{subbrandNAME}</option>
<option spry:if="{ds_RowNumber} != {ds_CurrentRowNumber}" value="{subbrandNAME}">{subbrandNAME}</option>
</select>

</span>
		</td>
</tr>
</table>

</cfoutput>
</form>

</code>
</pre>
<p>&#8230;and Spry takes care of the rest.</p>
<p>As I said before, this is a workable solution but I&#8217;m certain there are quicker and more efficient ways to get the same results with Spry without the XML hoops that I jumped through here. You can see a working copy <a href="http://www.rabidgadfly.com/sandbox/spryselects/mrselects.cfm">here</a>.</p>
<p>In researching, I attempted using <a href="http://ray.camdenfamily.com/projects/toxml/">Ray Camden&#8217;s toXML component</a> as well as the <a href="http://livedocs.adobe.com/coldfusion/6/Developing_ColdFusion_MX_Applications_with_CFML/XML12.htm">WDDX functionality provided by ColdFusion</a> but I just kept running problems passing the resulting datasets to the Spry methods.</p>
<p>Let me know if anyone out there has done anything similar using Spry. I&#8217;m interested in seeing the different possible solutions because it seems to me there are many.</p>
<p>-rG</p>
]]></content:encoded>
			<wfw:commentRss>http://rabidgadfly.com/2007/02/experimenting-with-multi-related-selects-using-spry/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>

