structFilter() UDF - Filtering a structure based upon a regular expression

Categories: HTML/ColdFusion

Today I thought I'd share a little ColdFusion helper function I've been using for years: structFilter(). The structFilter() parses a structure and returns only the keys that match a given regular expression.

<!---
 Searches a structure for keys matching a regex and returns a structure containing the
 matched keys.

 @param input        The structure to filter. (struct; required)
 @param regex        The regular expression to filter keys against. (string; required)
 @param useNoCase    Do a case insensitive search? (boolean; default = true)
 @param useDeepCopy  Do a deep copy on the keys? (boolean; default = false)

 @return Returns a structure containing the matching keys.
 @author Dan G. Switzer, II (dan.switzer@givainc.com)
 @version 1, June 17, 2009
--->
<cffunction name="structFilter" returntype="struct" output="false" access="public" 
    hint="Filters keys in a structure to those matching the regular expression.">
  <!---// define valid arguments //--->
  <cfargument name="input" type="struct" required="true" />
  <cfargument name="regex" type="string" required="true" />
  <cfargument name="useNoCase" type="boolean" required="false" default="true" />
  <cfargument name="useDeepCopy" type="boolean" required="false" default="false" />
  
  <!---// define local variables //--->
  <cfset var result = structNew() />

  <!---// if using NoCase and the (?i) directive doesn't exist, append to regex //--->  
  <cfif arguments.useNoCase and not reFind("^\(\?[mx]*i[mx]*\)", arguments.regex)>
    <cfset arguments.regex = "(?i)" & arguments.regex />
  </cfif>

  <cfloop item="key" collection="#arguments.input#">
    <cfif reFind(arguments.regex, key)>
      <cfif arguments.useDeepCopy>
        <cfset result[key] = duplicate(arguments.input[key]) />
      <cfelse>
        <cfset result[key] = arguments.input[key] />
      </cfif>
    </cfif>
  </cfloop>

  <!---// return the new structure //--->  
  <cfreturn result />
</cffunction>

I've found this helper UDF to be extremely handy in when you have a bunch of serialized form fields that follow a given nomenclature. For example, if you have a bunch of form fields like:

<input type="text" name="name" value="" />
<input type="text" name="description" value="" />

<!---// dynamic list of variables //--->
<cfloop index="i" from="1" to="10">
  <cfoutput>
    <input type="text" name="id_#i#" value="" />
  </cfoutput>
</cfloop>

Using the structFilter() UDF you can vary easily process all the fields starting with "id_" by doing:

<!---// 
  get all the fields:
  * starting with "id_"
  * and ending with one or more numbers
//--->  
<cfset stIds = structFilter(form, "^id_\d+$") />

This will give you a structure containing all the "id_" fields that you can then process in a collection-based loop. This method is much more effective then passing in some kind of hidden "counter" variable where you loop from 1 to the counter variable (which is a technique I've used in the past) as it doesn't rely on the numbers being serialized.

There are obviously many other uses for this function, but I use it a lot for processing complex forms that have dynamically generated fields that have a fixed nomenclature.

Safari 4 z-index issue with Flash

Categories: HTML/ColdFusion, Flex/Flash

I was doing some testing with Safari 4 (on Windows Vista) and noticed that it was running into the z-index issue that's normally fixed by having a wmode attribute. The issue is that Flash was always displaying on top of all other elements. Normally this can be fixed by applying the wmode attribute of either "opaque" or "transparent" to your SWF, however that was already present.

After playing around with the problem for a good bit trying various solutions of applying an z-index to elements, I decided to check to see if I had the latest version of Flash installed. Turns out I was running Flash 10,0,22,54 and 10,0,22,87 is the latest version. Sure enough, after upgrading Flash everything started working as expected.

So, if you're having problems with Flash being overlaid over all of your elements in Safari, try upgrading to the latest version of Flash to see if it fixes the problem.

(To see how things should work, check out http://pipwerks.com/lab/swfobject/z-index/2.0/dynamic.html. If mousing over the menu options is not showing some pop-up elements, then something has gone awry—so try upgrading Flash.)

CFHTTP "Connection Failures" issues when using mod_rewrite

Categories: HTML/ColdFusion

Several years ago I ran into some issues with CFHTTP giving "Connection Failures" when using GZIP, but recently I ran into some new "Connection Failures" when using CFHTTP. I recently installed some mod_rewrite rules on our server to:

  • Redirect naked domains to the www subdomain (i.e. map domain.com to www.domain.com)
  • Force SSL

My rules were pretty simple and worked great when invoked from the browser, but I quickly realized they were causing issues with CFHTTP.

Pagination in MSSQL 2005 with one-to-many joins

Categories: HTML/ColdFusion, SQL

I was working on restructuring some old code that needed some pagination. The query in question used a one-to-many join the required information together. Imagine a search engine where you're wanting to search over orders, but want to group the results by customer. The output might look something like:

Gary Dell'Abate
  Order #: 12098
  Order #: 13232
  Order #: 14551
  Order #: 16770
Fred Norris
  Order #: 11021
  Order #: 11029
Robin Quivers
  Order #: 10010
  Order #: 11001
  Order #: 12001
Howard Stern
  Order #: 13001

So, in my situation I want to also paginate by the customers. When SQL Server 2005 was introduced, it added a new feature called Common Table Expressions (CTEs.) One of the most useful features of CTEs is to paginate recordsets. Typically when paginating results, you will use the row_number() function—which creates a new unique row number for each row in your recordset:

Targeting specific Browsers with CSS

Categories: HTML/ColdFusion

Pail Irish posted a nice concise list of CSS hacks for targeting specific browsers. While I'd love to avoid using hacks altogether, I just continually find cases where it's necessary so this list is a handy little reference:

/***** Selector Hacks ******/
 
/* IE 6 and below */
* html #uno  { color: red }
 
/* IE 7 and below */
*:first-child+html #dos { color: red } 
 
/* IE 7 and modern browsers */
html>body #tres { color: red }
 
/* Modern browsers (not IE 7) */
html>/**/body #cuatro { color: red }
 
/* Opera 9.27 and below */
html:first-child #cinco { color: red }
 
/* Safari */
html[xmlns*=""] body:last-child #seis { color: red }
 
/*safari 3+, chrome 1+, opera9+, ff 3.5+ */
body:nth-of-type(1) #siete { color: red }
 
/* safari 3+, chrome 1+, opera9+, ff 3.5+ */
body:first-of-type #ocho {  color: red }
 
/* saf3, chrome1+ */
@media screen and (-webkit-min-device-pixel-ratio:0) {
 #diez  { background: #FFDECE; border: 2px solid #ff0000  }
}
 
/***** Attribute Hacks ******/
 
/* ie6 and below */
#once { _color:blue }
 
/* ie7 and below */
#doce { *color: blue } /* or #color:blue */
 
/* 'Modern Browsers' includes IE8, whether you agree or not.. :) */

I did notice that the "*" hack (i.e. "*color: blue") also seems to get picked up by IE8, while he lists the hack as for being for IE7 and below.

Paul even set up a test page with all the hacks for testing.

Nice job Paul!

Ganymede Mylyn v3.1.1 not working with Trac 0.10.4

Categories: HTML/ColdFusion

I recently upgraded to Eclipse 3.4.2 (Ganymede) and started having problems connecting to Trac. I didn't have any problems with Mylyn v2.3.2 in Eclipse v3.3, so I knew there were no configuration issues my installation.

The first thing I did was bust out an HTTP proxy tool so I could view the HTTP traffic being sent. Turns out that Mylyn was not sending the authentication header, so my servers was just spitting back a 401 authentication failed message.

I did a lot of searching and finally found the authentification fails with mod_auth_sspi or NTLM issue in the Mylyn bug tracker—which appears to be the exact issue I'm having, but alas upgrading to even the weekly (Mylyn v3.2) did not fix the problem.

Finally, I decided to just uninstall all the versions of Mylyn I had installed, but v3.0.5 that came with my Ganymede installation. To do that, you've first got to disable all the plug-ins and then you can uninstall.

Fortunately, rolling back to v3.0.5 has gotten me up and running again.

NOTE:
Our Trac server is running Apache 2.4 with Trac 0.10.4. We also are using SSL with a custom cert and using Windows Authentication.

Eclipse showing .svn-base files in "Open Resource" dialog…

Categories: HTML/ColdFusion, Java

Recently after installing a fresh copy of Eclipse 3.4 on my PC, I ran into an issue with the "Open Resouce" dialog ([CTRL]+[SHIFT]+[R]) where it was showing all my SVN files. Installing Subclipse is supposed to make the Eclipse IDE automatically hide the .svn-base files from showing up (via the "Team" interface) but it wasn't working out for me.

Turns out there was a very easy solution to this problem—just right click on the project and choose "Close Project" from the menu. After the project closes, just right-click on the project and select "Open Project." This should reinitialize all the settings on a project and appears to registered the handling of automatically hiding the .svn-base files.

An alternative, would be to add the find your org.eclipse.ui.ide_3.4.*.jar (org.eclipse.ui.ide_3.4.2.M20090127-1700.jar) and then modify the plugin.xml file to include the filter "*.svn-base". I don't like this option because it requires you to change a JAR that could later be updated.

If you choose that route, close Eclipse and open the JAR with a Zip extraction tool. Next, search the plugin.xml for the text "<filter". There should be one filter tag:

Flash + IE7 + SSL + XML = Epic Fail…

Categories: HTML/ColdFusion, Flex/Flash

Yesterday I ran into a very weird issue that one of our users reported. They complained that a Flex component was not working. Originally they described the problem as the Flash wasn't loading at all, but after digging around (and having the user send a screenshot) I realized the Flash was running, but it just wasn't getting the data.

Sure enough, I fired up Internet Explorer 7 and I saw the exact same issue. This was working fine in other browsers (such as Firefox, Safari and Chrome.) I was also having no issues using SSL on our development server. All I can think was "WTF?"

So, off to Google I went looking for an answer.

After some digging, I finally came across Mark Speck's IE7 + SSL + XML? = Flex "Error #2032: Stream Error" post. While I had found a number of similar posts declaring the same problem, every other article I found indicated this was only a problem if the "Cache-Control" header was being sent—which my production server was not sending. However, Mark also documented that this issue could occur with no "Cache-Control" heading—which matched what my production server was doing.

Since I wanted to be able to handle this problem programmatically (because I didn't want this issue to crop up again if we ever migrate servers or add more servers to the cluster,) I decided the best method to solve this problem was to serve up the XML dynamically using ColdFusion. I was able to resolve the problem by moving my XML into a CF template with the following code:

<!---// send the headers //--->
<cfheader name="Content-type" value="text/xml" />
<!---// this is required so IE7 will load the XML over SSL //--->
<cfheader name="Cache-Control" value="no-store, must-revalidate" />
<cfheader name="Pragma" value="public" />
<cfheader name="Expires" value="-1" />
<cfcontent reset="true" />
<xml>
    <goes />
    <here />
</xml>

Thankfully this resolved the issue.

However, I was never able to figure out why I was not having the problem in our development environment. The headers were virtually the same between the two servers. I'm beginning to think this problem might have also been related to the static XML being served via GZIP over SSL, but my dynamically served file is still being GZIP and is using SSL—so I'm not positive GZIP played a part.

I did find one other solution and that was to serve the static XML over HTTP instead of HTTPS. However, we're forcing traffic over SSL, so that option would work for us.

Vince Bonfanti gets OpenBlueDragon CFML engine running on Google Apps

Categories: HTML/ColdFusion

I thought this would hit the blogsphere a little harder, but Vince Bonfanti was able to get a heavily modified version of Open BlueDragon running on Google Apps. The announcement is a bit buried in a Google Group list for Open Blue Dragon, but the announcement is pretty exciting, because it opens up a new alternative for hosting a ColdFusion application and it's free for pageviews less than 5 million a month.

Here's what Vince had to say about what was required to get things running:

No, this wasn't done using precompiled CFML templates--it's running a
"raw" CFML page just as you normally would.

The Google App Engine (GAE) puts a number of restrictions on Java
servlets, the most significant for OpenBD are: (1) you can't write to
the file system (but you can read from it); (2) you can't create
"background" threads; (3) you can't use any of the java.net.* classes;
and, (4) you can't use any of the java.awt.* classes. There are a
number of other restrictions when accessing the Java class libraries.

Basically, I modified the OpenBD code to workaround these
restrictions. This meant things like not writing out the
bluedragon.xml configuration file, writing logs to System.out instead
of the bluedragon.log file, disabling runtime error logging, etc. It
also meant removing or disabling some features, such as CFCHART,
CFTHREAD, CFHTTP, CFLDAP, CFMAIL, CFSCHEDULE, etc., which won't run in
the GAE environment due to the Java class library restrictions.

We still have a bit of work to do to clean this up to make it ready
for public consumption. I've handed this off to Alan Williamson, who's
going to work on modifying CFQUERY to work with the datastore (GAE
does not support SQL datasources).

While we're working on this, I'd recommend becoming familiar with the
Google App Engine for Java:

http://code.google.com/appengine/docs/java/overview.html

I'd especially recommend becoming familiar with the Eclipse plug-in:

http://code.google.com/appengine/docs/java/tools/eclipse.html

As you can see, there's a lot of modifications that were required and some that may even be deal killers depending on your requirements, but there's still plenty of opportunities to build something exciting.

This would be an excellent way to put an idea to production without investing anything but your time.

Illustrating how sorting algorithms work with animations…

Categories: HTML/ColdFusion, JavaScript

I ran across a cool site today called Sorting Algorithm Animations. The site covers 8 popular sorting algorithms and gives you animated illustrations so you can see how each sorting algorithm works. You can even run the animations for all sorting methods at the same time to see how each compare in performance to one another.

What's really interesting is that it shows there is no "best" sorting algorithm. While "bubble" sorting works great when the data is nearly sorted, it's horribly slow when the data is ordered in reverse order. Other methods tend to perform about the same regardless of the randomness of it's data.

The other nice thing is that it details the algorithm used for each sort technique.

This is a great resource if you need to roll out your own sorting algorithms and are trying to decide which algorithm makes the most sense for you application.

ColdFusion UDF for detecting jQuery AJAX operations…

Categories: HTML/ColdFusion, jQuery

Raymond Camden justed posted an article on detecting jQuery AJAX operation using ColdFusion. I honor of that post, I thought I'd share the UDF I've been using in my application for quite some time:

<cffunction name="isAjaxRequest" output="false" returntype="boolean" access="public">
    <cfset var headers = getHttpRequestData().headers />
    <cfreturn structKeyExists(headers, "X-Requested-With") and (headers["X-Requested-With"] eq "XMLHttpRequest") />
</cffunction>

The code uses the exact same logic the technique in Raymond's post, but having the code in a function makes your detection code a lot easier to read.

Now when you want to detect if a request came from an AJAX operation, you can just do:

<cfif isAjaxRequest()>
    Came from jQuery! :)
<cfelse>
    Didn't come from jQuery. :(
</cfif>

Doesn't get any easier than that!

Tool to help improve readability of your website…

Categories: HTML/ColdFusion

One problem that can often come up when designing a web site is problems with legibility of the text on your web site. You might have issues with kerning, line spacing, font size and even the contrast between the foreground text and the background color.

The tool I'm sharing with you today is one to help ensure that you have proper contrast between the foreground text and your background color.  The color contrast tool uses the W3C has formulas developed by the W3C to detect sufficient contrast between your text and the background color.

I originally got the idea from the Color Contrast Check tool, and while it's really helpful fine tuning settings, it didn't really help through out some suggestions of colors that are close to my original but that will improve the contrast/brightness differentials.

That's what makes the Color Contrast Tester unique. If your contrast/brightness levels aren't sufficient it'll work on some variations that improve the differential. While the tool isn't perfect, I've found it extremely useful over the past 6 months since I developed it.

Using it is simple, just plug in the hex values for the foreground and background colors and it'll give you your brightness and contrast differences and then suggest some variations that pass what the W3C suggests as being appropriate.

Let me know what you think!

Color Contrast Tester

BlogCFC v5.9.3.000 released…

Categories: HTML/ColdFusion

Well, I'm proud to say I just helped Raymond release a new version of BlogCFC—version 5.9.3.000. Hopefully the "Switzer" edition doesn't become known as the version that made BlogCFC jump the shark. :)

A lot of the mods I contributed were related to the XML-RPC stuff, since I post almost exclusively from Live Writer and only go into the Admin when I need to set up related entries. However, one change that I think everyone might like is I added a "Comments" tab to the entry page. I added this to my version of BlogCFC way back in November of 2007 because I found I was usually trying to find comments related to a specific entry and they were hard to find via the normal comments page.

Here's a summary of the changes:

  • Updates/simplification of file pathing determination
  • XML-RPC updates (yes, I did test these myself, I don't suck) ;)
  • Admin has a nicer warning when settings/cache is updated
  • When you edit an entry, you get immediate access to the comments (new "Comments" tab)
  • Ability to view an unreleased entry on the blog. This lets an admin see how an entry will REALLY look w/o having to release it.
  • Code coloring updates (the blue HTML tag color and Attribute color were so close they looked identical, so I gave the HTML tag a color that adds better contrast)
  • HTML entities are cleaned out of the Subject of e-mails and removed from the title shown in the e-mails (probably only an issue if you use a WYSIWYG Blog editor)

Managing JavaScript events/functions using "debouncing"

Categories: HTML/ColdFusion

Yesterday I came across a very timely post by John Hann on Debouncing Javascript Methods. I say timing, because this was a problem I was just getting ready to solve again for umpteenth time—managing rapidly fired events in JavaScript.

I was working on some live search functionality for a page where I was searching DOM elements and populating a list of matching elements. Since this was a "live" search, I'm doing the update as the user types. The trick to this issue is that you don't really want to fire off the process each time the user presses a key, but instead you want to really fire it off when there's been a delay/pause to their typing. If you actually do the processing on each character, many of the calls you're making become quickly invalidating as the input changes so quickly that you end up making unnecessary calls. You'll also see a noticeable slow down in performance if your process is CPU intensive.

You can run into the same issue when dealing with AJAX operations. If you're just updating some portion of the screen based upon some user interaction, you really only want to fire off the AJAX call when the user is done interacting with the element.

This is where John's debounce solution comes into play.

Internet Explorer 8 issues with Compatibility View & EmulateIE7...

Categories: HTML/ColdFusion

So, Internet Explorer 8 was just officially released. First off, I was really impressed with the download speeds. In the past downloading Day 0 releases from Microsoft have always been a bit problematic for me—because of the sheer volume of download requests. However, my download experience was very fast. Kudos Microsoft.

However, one of my main gripes from RC1 is still present—Compatibility view doesn't work consistently. If you're not aware, the following meta tag is supposed to force IE8 to run in Compatibility view:

<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />

However, I'm still noticing issues that are inconsistent between adding this to the HTML and a user manually activating Compatibility View for a site.

The quickest way for me to illustrate this is to show you some screenshots.