Skip to main content
Known Participant
December 24, 2008
Question

Shopping Cart -adding multiple items at once

  • December 24, 2008
  • 3 replies
  • 663 views
I need to build a shopping cart where a list if items is presented including a text field for quantity. But instead of each item having it's own "add to cart" form where a user adds each item to the cart one item at a time - the user needs to be able to go through the list, adding quantities to each item they want, then submit one button to add all items selected.

I can't seem to get my head around setting this up, nor can I find an example of where it has been done. Something like:
<FORM> <cfoutput>
item 1 <input type="hidden" name="#id#" value="#id#"><input type="text" name="#id#addQty">
item 2 <input type="hidden" name="#id#" value="#id#"><input type="text" name="#id#addQty"> </cfoutput>
<input type="submit" name="submit">
</form>

If I use the above, how best to deal with the submitted form data? The field names will vary, based on the list of items. Or, is there simply a better way to do this.
    This topic has been closed for replies.

    3 replies

    Inspiring
    December 24, 2008
    You could name the fields with a counter variable. So the field names are consecutive: quantity_1, product_1, quantity_2, product_2, ... The total number of fields should be stored in a hidden field, outside the loop.

    <cfloop ....>
    <input type="hidden" name="productID_#counter#" value="#productID#">
    <input type="hidden" name="quantity_#counter#" value="">
    </cfloop>
    ..
    <input type="hidden" name="numberOfFields" value="...">

    Then you can use the total number of fields in a loop to iterate through each set of form fields.

    <cfparam name="form.numberOfFields" default="0">
    <cfoutput>
    <cfloop from="1" to="#form.numberOfFields#" index="x">
    <cfset variables.productID = form["productID_"& x]>
    <cfset variables.quantity = form["quantity_"& x]>

    <cfif len(trim(variables.quantity)>
    The form.quantity_#x# = #variables.quantity#<br>
    </cfif>

    </cfloop>
    </cfoutput>

    But that is just one option. There are others. Edit: You could also use list functions instead of multiple comparisons. For example

    <cfif not listFindNoCase("submit,did,fieldnames", varname)>
    ...
    </cfif>
    Inspiring
    December 24, 2008
    Preserved wrote:
    > <cfif #varname# is not "submit" and #varname# is not "DID" and #varname# is not "FIELDNAMES">

    BTW, the # signs are not needed. CF can evaluate the values of the variables without them

    ie: <cfif varname is not "submit" and varname is not "DID" and varname is not "FIELDNAMES">
    PreservedAuthor
    Known Participant
    December 24, 2008
    Thanks Ian,

    That gets me closer. Now that I can get all the fields, I want to separate the fields out (products), and check for a value in the field. In other words, I want to get just the fields where a user has put a a number is a text field.

    I have this that almost gets me there, but in a very clunky way:


    <CFLOOP COLLECTION="#Form#" ITEM="VarName">
    <CFOUTPUT>
    <!---remove what I don't want --->
    <cfif #varname# is not "submit" and #varname# is not "DID" and #varname# is not "FIELDNAMES">
    <!---check to see if there's a value in the text field --->
    <cfif #Form[VarName]# is not "" >
    #VarName# #Form[VarName]#<br>
    </cfif>
    </cfif>
    </CFOUTPUT>
    </CFLOOP>

    Is there a more elegant way of doing this?
    Inspiring
    December 24, 2008
    Preserved wrote:
    >
    > If I use the above, how best to deal with the submitted form data? The field
    > names will vary, based on the list of items. Or, is there simply a better way
    > to do this.
    >

    I don't see the need for the hidden fields at this time, but it does not
    really matter.

    For dealing with dynamically named form elements the usual foundation
    cornerstones are the form.fieldnames, array notation of the form
    structure and|or structKeyList.

    Since a form, and all other CFML variable scopes, are structures you can
    use array notation to access any element. I.E.

    <cfset id = 12>
    <cfoutput>#form[id & 'addQty']#</cfoutput>

    You can inspect either #form.fieldNames# or #structKeyList(form)# to get
    a list of all field names listed.

    You can loop over the form structure with structure loops.

    <cfoutput>
    <cfloop collection="#form#" item="field">
    form.#field# = #form[field]#<br/>
    </cfloop>
    </cfoutput>

    That should get you started. Come on back if you have more specific
    questions.