Processing forms with duplicate field names

Recently Ben Nadel posted a blog entry that was in reply to an earlier entry of mine. Both entries talk about passing arrays of data to the server via client side JavaScript. In the comments we got a bit side tracked into talking about how to handle multiple form fields with the same name. What do I mean? Consider a form that looks like this:


<form action="test4a.cfm" method="post">
<input type="text" name="name" value="Camden,Raymond">
<input type="text" name="name" value="Smith,John">
<input type="submit">
</form>

Notice that I have two fields with the name “name.” This is kind of dumb, but I’ve seen it many times before. And while you may not ever code this, you may be working on code that listens for posts from remote services. Those services may choose to send their data like that and not leave you with much choice.

ColdFusion will nicely take those two form fields and combine them into one form.name value. ColdFusion will also nicely turn the two values into one – a list. However, look at my values. They both have commas already. When submitted, I end up with form.name being “Camden,Raymond,Smith,John.” There is no way to tell what my data really was.

I did a quick test though and looked at how getHTTPRequestData saw the values. I began by dumping the form scope and dumping the result of getHTTPRequestData():

Notice that the form scope is as I described – a list of munged data that we can’t use. The result of getHTTPRequestData, however, is more clear. Notice specifically the content value:

name=Camden%2CRaymond&name=Smith%2CJohn

We’ve got a list of URL encoded values. Most importantly – the list of values are separate. What this means is that we can quickly turn this into a proper array:


<cfset data = []>
<cfif len(req.content)>
<cfloop index="item" list="#req.content#" delimiters="&">
<cfset arrayAppend(data, urlDecode(listLast(item, "=")))>
</cfloop>
</cfif>

As you can see, I simply treat the value as a & delimited list. For each item, I get the value to the right and urlDecode it. I append this to an array and I end up with my two values. Obviously this assumes that everything in the list is a NAME value. That would not be true if there were more form fields. But I think this is enough to give you a good start if you do indeed need to work with form data of this type.