Form Data in Field Order

I've been working to create a ColdFusion drop-in replacement for the venerable FormMail perl script from Matt's Script Archive. One thing that had me scratching my head for many weeks was how to retrieve and output the submitted form fields in the same order they appeared in the html form.

The perl FormMail script did it by reading the STDIN buffer for the size of the $ENV('CONTENT_LENGTH'). Well, that's tough to translate into ColdFusion. I tried all kinds of functions in the GetPageContext().getRequest() object: getInputStream, getAttributeNames, getParameterMap, getParameterNames, getQueryString. There is some interesting stuff in there, but none of it was sorted in the order I wanted. And obviously the URL and FORM scope structures are sorted alphabetically. How could something so easy in Perl be so hard in ColdFusion? On Friday I was reading comments on a blog that prompted me to go down a slightly different path.

Mike Nimer from Adobe had an old blog entry on reading the http headers using some underlying java calls to get retrieve JSON data sent through in the http header. Well, I tried the code he had, but since I wasn't doing any JSON, there was no data to read.

Then Dan G. Switzer, II posted a comment discussing the native getHttpRequestData() function and the structure key called "content". Could it be the Holy Grail I was searching for these many weeks?

As it turns out, yes! God bless you Dan G. Switzer! The content key contains the form field name and value in the exact order they were in the HTML form and formatted similar to how the CGI.QUERY_STRING variable lists them. So getHttpRequestData().content returns something like:

field1=1&field3=2&field3=3&field2=4
which was the result of four form fields, two of which had the same name. So doing this:
<cfset dataArray=ListToArray(getHttpRequestData().content, "&")>
<cfloop list="#getHttpRequestData().content#" index="data" delimiters="&">
   <cfset field=ListFirst(data, "=")>
   <cfset value=ListRest(data, "=")>
   <cfoutput>#field# = #value#<br /></cfoutput>
</cfloop>
returns something like this:
field1 = 1
field3 = 2
field3 = 3
field2 = 4
Problem solved!

Related Blog Entries

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
Why not just pass in a hidden field which contains a list of the field names in the order that you want them to be displayed in?
# Posted By Jordan Clark | 9/24/07 6:24 PM
erm, what about Form.fieldnames ?
# Posted By some guy | 9/24/07 9:05 PM
Jordan:
The idea is to be able to add one or two hidden fields to a form and have the results e-mailed to you. You don't want to have to update the list of field names every time you add/edit/remove a field!

Some guy:
Mmmm, guess you learn something everyday--they do appear to be in form order. Of course they are in ALL CAPS...
# Posted By Mark Mazelin | 9/24/07 11:07 PM
BlogCFC was created by Raymond Camden. This blog is running version 5.8.