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:
- Tests for the existence of a parameter (that is, a variable).
- Validates its data.
- 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.
Want to use code from this post? Check out the license.