Problems with CF 8's Generated Keys Feature

So you may have read about CF 8's new ability to return generated keys. For SQL Server 2000 and greater this means that the driver attempts append the SELECT SCOPE_IDENTITY() statement to end of insert statements. If you want to get an idea of how this is done you can take a look at the source for the jTDS JDBC driver. While the jTDS driver isn't what ships with ColdFusion, you can bet that CF's SQL Server driver from DataDirect is doing something similar. In fact you can actually confirm this using SQL Profiler.

[More]

Foundations

Anyone who has studied OO programming has probably knows that the idea of design patterns originated in the field of architecture. In fact there are quite a few practices and paradigms the software and construction industries share. I've seen a few examples of this recently in the building of 20 new rowhomes next door to mine.

[More]

Spry AutoSuggest With Multiple Parameters

When loading datasets from the server for for the Spry AutoSugget widget, Spry passes the value of the search field as a parameter to the dataset URL. This works fine, but what if the suggestions you want to provide are based on a combination of form fields?

To give you a better of idea of what I mean, here is an example of a search form I was working on earlier today: (Note: this form doesn't work.)

Find users within of the following :

I wanted to provide suggestions for the search term, but I wanted to limit those suggestions to only the country (U.S. or Canada) and type (City or Postal Code) selected. So if a user selects U.S. Cities they should only get U.S cities as suggestions, no Canadian cities or postal codes of any kind. This turned out to be fairly easy but I though I'd share my approach in case others are interested.

Basically what I needed to do is append multiple parameters to the dataset URL. To accomplish this I added a new function to the Spry AugoSuggest widget named addReplaceParams:

Spry.Widget.AutoSuggest.prototype.addReplaceParams = function(params)
{
   
   var ds = this.dataset;
   ds.cancelLoadData();
   ds.useCache = false;
   
   this.setValue('');
   this.showSuggestions(false);
      
   var url = ds.url;
   
   for(var i=0; i < params.length; i++) {   
      url = Spry.Widget.Utils.addReplaceParam(url, params[i].param, params[i].value);   
   }      
   
   ds.setURL(url);
   ds.loadData();
   
};
In a nutshell this function clears the search term, hides suggestions and updates the AutoSuggest's dataset URL using an array of parameters passed to the function. The parameters are defined as simple JavaScript objects with two keys: param which is the name of the URL parameter, and value which is the value of the URL parameter. It does the actual parameter additon/replacement using the Spry.Widget.Utils.addReplaceParam() function. To update the URL using this function I wrote another function which I use as the onChange event handler for the country and type select elements.
function updateDsURL(f){
   
   var country = f.radiusCountry[f.radiusCountry.selectedIndex].value;
   var type = f.radiusType[f.radiusType.selectedIndex].value;
   
   var params = [];
   params[0] = {param:'radiusCountry',value:country};
   params[1] = {param:'radiusType',value:type};
   
   theSuggest.addReplaceParams(params);   
};

Putting it all together this is what it looks like:

<html>
<head>
<script language="JavaScript" type="text/javascript" src="includes/xpath.js"></script>
<script language="JavaScript" type="text/javascript" src="includes/SpryData.js"></script>
<script language="JavaScript" type="text/javascript" src="includes/SpryAutoSuggest.js"></script>
<link href="includes/SpryAutoSuggest.css" rel="stylesheet" type="text/css" />
<script language="JavaScript" type="text/javascript">
var ds1 = new Spry.Data.XMLDataSet("/suggestions.cfm","radiusvalues/radiusvalue");

function updateDsURL(f){
   
   var country = f.cboRadiusCountry[f.cboRadiusCountry.selectedIndex].value;
   var type = f.cboRadiusType[f.cboRadiusType.selectedIndex].value;
   
   var params = [];
   params[0] = {param:'radiusCountry',value:country};
   params[1] = {param:'radiusType',value:type};
   
   theSuggest.addReplaceParams(params);   
};


Spry.Widget.AutoSuggest.prototype.addReplaceParams = function(params)
{
   
   var ds = this.dataset;
   ds.cancelLoadData();
   ds.useCache = false;
   
   this.setValue('');
   this.showSuggestions(false);
      
   var url = ds.url;
   
   for(var i=0; i < params.length; i++) {   
      url = Spry.Widget.Utils.addReplaceParam(url, params[i].param, params[i].value);   
   }      
   
   ds.setURL(url);
   ds.loadData();
   
};
</script>
</head>

<body>
<form>
<p>
Find candidates within
<select name="radius">
   <option value="0" selected>Any Distance</option>
   <option value="1">1 mile</option>
   <option value="2">2 miles</option>
   <option value="3">3 miles</option>
   <option value="4">4 miles</option>
   <option value="5">5 miles</option>
   <option value="10">10 miles</option>
</select>
of the following
<select name="radiusCountry" onChange="updateDsURL(this.form);">
   <option value="U" selected>U.S.</option>
   <option value="C">Canadian</option>
   <option value="B">U.S. or Canadian</option>
</select>
<select name="radiusType" onChange="updateDsURL(this.form);">
   <option value="City"selected>City</option>
   <option value="Zip">Postal Code</option>
</select>:
</p>

<div id="mySuggest">
<input type="text" name="radiusValue"/>
<div id="resultsDIV" spry:region="ds1">
<ul>
<li spry:repeat="ds1" spry:suggest="{radiusvalue}">{radiusvalue}</li>
</ul>
</div>
</div>
<script type="text/javascript">
   var theSuggest = new Spry.Widget.AutoSuggest("mySuggest","resultsDIV", "ds1","name",{minCharsType:3, loadFromServer:true, urlParam:'filter'});
</script>

</form>
</body>
</html>

You may ask why two functions? Well, I thought this is something I may want to use again so I made the Spry.Widget.AutoSuggest.addReplaceParams() function fairly generic. For this example I included the function in the inline script block, but if I use it enough I'll probably end up putting it in my AutoSuggest.js file.

OK, that's one down...

ColdFire 1.002

Today Ray and I released ColdFire 1.002 which fixes a few minor issues with JSON encoding. If you were having problems with the variables feature of ColdFire this update may fix your issue. Be sure to update both the Firefox extension and coldfire.cfm debugging template. You can get both via the download at RIAForge.

We have also been discussing upcoming features so if there is something you would really like to see be sure to let us know via the RIAForge site.

Installing CF 7 on W2K3 SP 2

I was having some problems trying to install ColdFusion 7 on Windows Server 2003 SP 2 last week. The installer would complete with errors and ColdFusion wouldn't start. Looking at the installation log I was seeing a few ANT script errors plus the following:

Web Server Connector Configuration Error
Status: ERROR
Additional Notes: ERROR - JNDI port 2902 for server coldfusion is not active

I found a blog post and a TechNote that seemed close to what I was experiencing, but the solutions seemed like a pain. Then I remembered DEP. I was able to run the ColdFusion installer after changing the DEP settings as follows:

  1. Click Start, click Run, type sysdm.cpl, and then click OK.
  2. On the Advanced tab, under Performance, click Settings.
  3. On the Data Execution Prevention tab, click "Turn on DEP for essential Windows programs and services only" to select the OptIn policy.
  4. Click OK two times.

Just to be on the safe side I would recommend changing this setting back to the default OptOut policy after completing the installation. You can do this by using the steps above, only select "Turn on DEP for all programs and services except those I select" for step 3.

BlogCFC was created by Raymond Camden. This blog is running version 5.8.001.