CFParam And Regex-Pattern Is Quite Awesome

Posted November 19, 2007 at 7:15 AM by Ben Nadel

Tags: ColdFusion

I have been using ColdFusion's CFParam tag for a long time and have been really happy with it. Normally, however, I just use it to parameterize the existence and data type of string and numeric form values. In my Exercise List project, however, one of the form values that I was expecting was a comma delimited list of numeric IDs. This cannot be a numeric value because it contains non-numeric characters (the comma). It can be a string value, but this certainly doesn't help me to ensure that the data type is correct; meaning, making sure that it is a string does not mean that it will be a list of numeric IDs.

Enter the CFParam tag type of Regex and its partner in crime, the Pattern. Using a regular expression, we cannot only make sure that the list of IDs was submitted with the form, we can also make sure that it is truly a comma delimited list of numeric values. Take a look at this CFParam tag:

  • <cfparam
  • name="FORM.lst_item_id"
  • type="regex"
  • pattern="[\d,]*"
  • default=""
  • />

Here, we are saying that the form value, lst_item_id, must conform to the pattern "[\d,]*", or if it doesn't exist, that it is defaulted to the empty string. For those of you not versed in regular expressions, this pattern means "zero or more characters from the set composed of the comma and all numeric digits.

This is the first time that I have ever uses the regex / pattern CFParam type and I have to say that I am really excited about it. I love regular expressions and I am always happy to see that they can be put to a good use. But more importantly, I am finally utilizing the ColdFusion CFParam tag as it was intended to be used; if you look at the ColdFusion documentation, you will see that CFParam has three responsibilities:

  1. Tests for the existence of a parameter (that is, a variable).
  2. Validates its data.
  3. Provides a default value to the variable if one is provided.

Up until now, when it came to a list of IDs, I was using CFParam, but only for responsibilities #1 and #3 - existence and default value. I was guilty of not using the CFParam tag properly. I was guilty of not making its power work for me. But no longer - I see the light, baby, and I see it shining brightly.

Here is what I am thinking: If you have a list of CFParam tags at the top of your FORM processing action, then by the time those CFParam tags have finished executing, all of your FORM data should be of the proper data type; no more TYPE validation should need to be done, only value validation.

At first, I thought that there might be this exception: a text input field that requires a numeric value. Yes, you could perform all of the type validation via CFParam, and yes you could make sure that only a numeric value is available after the CFParam tags, but really, this is not a valid use case. A text input should NOT and cannot be paramed as a numeric data type as a text input box is not for numeric inputs - it's for text input. It's just by our own business logic that we then say that that text input must be numeric. This is a value validation, not a type validation.

Enforcing that a select box has a numeric value or a that checkbox has a numeric value is a valid data type validation as these interfaces are not supposed to have user-value manipulation outside of selection and checking. Text inputs, on the other hand, can only be paramed as text because it is an interface that does not force a user to enter only a certain type of data.




Reader Comments

Nov 19, 2007 at 8:21 AM // reply »
51 Comments

Very cool! I'm going to have to dust off my RegEx in 10 Minutes book!


Nov 19, 2007 at 8:57 AM // reply »
11,238 Comments

@Jim,

Luckily, I don't think you will have too many different types of expressions to use. When I think about form data type validation, here are the different data types I can think of:

* Text input (text, textarea, file)
* Numeric input (select, checkbox, radiobox)
* Text list
* Numeric list

Text inputs can be CFParamed with [type = string]. Numeric input can be CFParamed with [type = numeric]. Text lists can pretty much also be CFParamed with [type = string]. The numeric list, the one I am talking about in this post can use the regex / pattern CFParam.

There's probably others, but that's all I can think of at this moment. Shouldn't be too taxing for the regex part of your brain :)


Nov 19, 2007 at 10:09 AM // reply »
11 Comments

What does cfparam do if the value is defined but doesn't match the regex? Throw an error, or use the default value?


Nov 19, 2007 at 10:23 AM // reply »
11,238 Comments

@David,

It throws an error. Therefore, you should be wrapping them in some sort of CFTry / CFCatch tag group. Sometimes, I do it around all of them, sometimes I break out special CFParam tags into their own group. This is a bit of a pain, which is why I suggested that Adobe come up with a CFParam tag that has a "catch" attribute:

http://www.bennadel.com/index.cfm?dax=blog:594.view


Nov 19, 2007 at 10:29 AM // reply »
11 Comments

Interesting. I like the idea conceptually, but as mentioned by a few commenters on your previous post, the idea of throwing an exception for a validation failure seems a little extreme (even if the exception is caught in the same tag).


Nov 19, 2007 at 10:37 AM // reply »
11,238 Comments

@David,

Realize this, though - the data TYPE validation should never throw an exception unless someone has messed with the form submission process. This is an exception worth case; the data type that we excepted was not the data type that was submitted with the FORM.

Part of this confusion (and I am guilty of this as well) is not know the difference between data TYPE validation and data VALUE validation. Data types are not up for discussion - you set them and the FORM submits them (if no one has messed with the data). It is only in data VALUE validation that one can say, Ok, this "text" input is really supposed to be a "numeric" value. That has nothing to do with data types, only with data values. A subtle but hugely important differentiation.

Can you think of a time when your data types should not line up with what you expect them to be? The only thing I can think of is user-tampering; and, if that is the case, who cares if Exception handling is an expensive process? If a user is going to hack our forms, why should we even care if they are having the quickest user experience possible?


Nov 19, 2007 at 10:40 AM // reply »
11 Comments

Okay, now I'm confused. I'm talking about the case when the form input doesn't match the regex. According to your previous reply, that throws an exception, which has to be caught. My comment is that I'd prefer to catch that failed validation without throwing an exception.

I agree that throwing an exception when we know the form has been tampered with is reasonable. But I can think of lots of cases where input might not match the correct regex, but the form hasn't been tampered with.


Nov 19, 2007 at 10:50 AM // reply »
11,238 Comments

@David,

Be careful; you might be talking about validating the "value" of a "text box" input. If that is the case, what are you really doing there? Are you validating the "type" of data (string)? or are you validating the "value" of the data, which is not quite the same thing.

If you are talking about doing this for text inputs, I would say do not use regex / pattern. The user has far too much opportunity to mess it up.

As far as exception catching, this is for the TYPE validation, not the value validation.


Nov 19, 2007 at 10:53 AM // reply »
11 Comments

I see what you're saying now. In fact I think we're in agreement about this.


Nov 19, 2007 at 10:58 AM // reply »
11,238 Comments

@David,

Sweeeet :) I have only recently come this mental separation between type and value validation, so it might not be spot on, but something about it just makes me feel warm and fuzzy inside.


Nov 19, 2007 at 7:05 PM // reply »
14 Comments

Another thing along these lines that I have been thinking about and doing lately is:

If a url param is malformed, then logically that url is wrong, or if there is no record in the db for that id, the page does not exist...

<cftry>
<cfparam .../>
<cfcatch><cfinclude template="custom404.cfm"></cfcatch>
</cftry>

or

<cfif NOT query.recordCount>
<cfinclude template="custom404.cfm">
</cfif>

my custom 404.cfm page sets the http response code to 404 and provides a friendly interface. During regular use of the application, all links should go to pages that exist...


Nov 19, 2007 at 7:05 PM // reply »
14 Comments

Just another step in the validating and data checking processes...

BTW, I always like your blog posts. good work


Nov 20, 2007 at 7:10 AM // reply »
11,238 Comments

@Kevin,

Along the same lines, I usually do something like this:

<cfif NOT qData.RecordCount>
...
...<cflocation url="#CGI.script_name#" addtoken="false" />
...
</cfif>

Basically the same as what you are doing, except you probably have better 404 handling than I do.

And thanks for the kind words :)



Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 17, 2013 at 7:42 PM
HashKeyCopier - An AngularJS Utility Class For Merging Cached And Live Data
Ben - thanks so much for posting these Angular articles and findings, they've been a huge help towards learning one of the more 'complex' JavaScript frameworks out there (IMO). I have been using Angu ... read »
May 16, 2013 at 5:01 PM
UPDATE: Parsing CSV Data Files In ColdFusion With csvToArray()
Your code was the closest thing I've found to obtaining some direction for converting ISO fields to values that CF can translate properly. Thank you for posting! ... read »
May 15, 2013 at 10:37 PM
Very Simple Pusher And ColdFusion Powered Chat
hi id making plz easy ... read »
May 15, 2013 at 6:07 PM
Making SOAP Web Service Requests With ColdFusion And CFHTTP
Ben, you once again saved my bacon at work. Thank you, thank you, thank you! ... read »
May 15, 2013 at 4:15 PM
What If All User Interface (UI) Data Came In Reports?
@Josh, Thanks! @Ben, I definitely recommend the David West book "Object Thinking" I've been quoting from. It goes deeply into the philosophy and history of OO programming. His breadth ... read »
May 15, 2013 at 11:36 AM
Ask Ben: Print Part Of A Web Page With jQuery
I found this helpfull when you need to keep (refresh) the original parent page after closing the iframe child print dialog (Hoping you're not using a form at this time so it won't submit again): On ... read »
May 14, 2013 at 7:13 PM
What If All User Interface (UI) Data Came In Reports?
@Jonah, If there's any books you'd recommend on the subject of domain modelling, I'd love to hear it. I just downloaded the free PDF of "Domain Driven Design Quickly". Figured I'd give it ... read »
May 14, 2013 at 6:57 PM
The UX Of Prototyping: Low-Fidelity Is The New High-Fidelity
@Phillip, I'm not sure I follow what you mean? Are you saying that you looked at the list of widgets provided by the jQuery UI and let that be your style guide? ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools