<?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; spry</title>
	<atom:link href="http://rabidgadfly.com/category/spry/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 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>

