Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Send input from client as array of objects

New Here ,
Jul 06, 2011 Jul 06, 2011

Hi,

I'm developing an application with lots of repeated information from the client like

firstName1     firstName2     firstName3

lastName1     lastName2     lastName3

address1       addrress2      address3

city1             city2              city3

state1           state2            state3

zip1              zip2               zip3

and much more like date of birth, employer, etc.

I'm using form method=post.

Is it possible to receive this in my cfc method as an array of objects, or maybe just an array for each field? It would certainly make my life easier!

If yes could you please provide an example?

Thanks!

1.3K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jul 06, 2011 Jul 06, 2011

When I want to do stuff with form fields resembling that, I generally start with something like this:

<cfloop list="#form.fieldnames#" index="ThisField">

<cfif left(ThisField, somenumber) is "somestring">

do something with this information.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Jul 07, 2011 Jul 07, 2011

PHP does this nicely, and CF does too but it isn't very obvious. For example, instead of naming the fields firstname1, firstname2, firstname3, etc, you can name them all "firstname" and they will be posted in the order that they are laid out in the form. With this said, you can then access that form field as an array of values on the server side.

Try this method. On the page where your form is being posted to, do a <cfdump var="#getFormParams()#"> with this method defined on the page. Another thing this function does is checks the encoding type. Forms of multipart encoding are handled as a MultipartRequest from the com.oreilly.servlet package where as your standard form post is handled by the HttpServletRequest

<cffunction name="getFormParams" access="public" output="false" returntype="struct"
               hint="Returns a collection of form params regardless of the encoding type">
     <cfset var arParts = form.getPartsArray()>
     <cfset var isMultipart = structKeyExists(local, "arParts")>
     <cfset var stcParams = {}>
     <!--- If the form is multipart, we will loop through the array created
            internally by the com.oreilly.servlet.MultipartRequest class --->
     <cfif isMultipart>
          <cfloop array="#arParts#" index="part">
               <!--- Check to see if the param has been found already. If so, append
                      any duplicate params to the same array --->
               <cfif part.isParam()>
                    <cfif NOT structKeyExists(stcParams, part.getName())>
                         <cfset stcParams[part.getName()] = [part.getStringValue()]>
                    <cfelse>
                         <cfset arrayAppend(stcParams[part.getName()], part.getStringValue())>
                    </cfif>
               <cfelseif part.isFile()>
                    <cfif NOT structKeyExists(stcParams, part.getName())>
                         <cfset stcParams[part.getName()] = [part.getFileName()]>
                    <cfelse>
                         <cfset arrayAppend(stcParams[part.getName()], part.getFileName())>
                    </cfif>
               </cfif>
          </cfloop>
     <cfelse>
          <!--- It's wasn't a multipart form so we will get the param map from
                 the HttpServletRequest object --->
          <cfset stcParams = getPageContext().getRequest().getParameterMap()>
     </cfif>
    
     <cfreturn stcParams>
</cffunction>

Assume your form is the following:

<form action="page.cfm" method="post">

     <input type="hidden" name="names" value="tristan" />

     <input type="hidden" name="names" value="joe" />
     <input type="hidden" name="names" value="bob" />

</form>

page.cfm

<cfset arNames = getFormParams()["names"]> --> ['tristan', 'joe', 'bob']

This is also very helpful when you have fields with the same names and values that can't easily be accessed by using the "traditional" looping as suggested previously. If instead of "tristan" the value submitted had a comma in it, doing it the standard way by access the FORM scope could result in incorrect assumption of the data. If the value "tristan" was really "lee, tristan", here is how it would be handled in both ways:

<cfset arNames = listToArray(form["names"])> --> ['lee', 'tristan', 'joe', 'bob']
<cfset arNames = getFormParams()["names"]> --> ['lee, tristan', 'joe', 'bob']

Notice how by accessing the key in the FORM scope to get the list of values assumes that "lee" and "tristan" are 2 seperate values... that's wrong.

Hopefully this helps...

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Jul 13, 2011 Jul 13, 2011

Also keep in mind that certain HTML fields (checkboxes, radio buttons) will not pass an entry in the Forms scope to your action page if they are unchecked on the original form.  If you were to refer to the position of the element in your array, this could result in an array out of bounds error as the array that stores the checkbox/radio button data would have a different number of elements.  Though I have to say, this solution is pretty slick if you don't have any checkboxes/radio buttons to worry about.

Alternatively, the suggestion of giving all your fields a prefix (e.g. user1_firstname, user2_firstname, etc) would allow you to group and process your fields by looking over the form.fieldnames variable like the previous poster suggested.  It might also make integrating a more interesting front-end a little easier as you could associate a unique ID with each field, instead of having multiple form fields have the same name which could cause some client-side validation headaches.

Thought that might help.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jul 13, 2011 Jul 13, 2011

Here is the full CFC with another method 'fieldToArray'. As mentioned above, if the form element was on a certain type, it would not be passed or the length of the array could be different from how it should be, thus causing you out of bounds exceptions.

http://pastie.org/pastes/2208697/text?key=rbgsi2sqbtlvwm1y8wsqea

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Jul 13, 2011 Jul 13, 2011
LATEST

insuractive wrote:

Though I have to say, this solution is pretty slick if you don't have any checkboxes/radio buttons to worry about.

Yep.  (If you are interested in the underlying stuff, I wrote an entry on it a ways back). IMO the first method is better suited for cases where you need to maintain value integrity, but not group values. When you need to group related fields, as in this case, the second option (ie common suffix/prefix) is better.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources