You can accomplish that... but to do so you need to understand what's going on behind the scenes. While not yet syntactically correct, your current sample code looks like it's looping for each item in the cart, and displaying several text fields (hidden and otherwise) on each loop. Problem is you're naming them all the same.
So your form wants to come out looking like:
Code:
<form action="IreallyShouldHaveApagenameHere!" method="post">
<table>
<input type="hidden" name="itemindex" value="1">
<tr><td>Some item <input type="hidden" name="item" value="Some Item"></td>
<td><input type="text" name="quantity" value="3"></td>
<td>$5.00 <input type="hidden" name="price" value="5.00"></td>
<td align="right">$15.00<input type="hidden" name="sub_total" value="15.00"></td>
</tr>
<input type="hidden" name="itemindex" value="2">
<tr><td>Some other item <input type="hidden" name="item" value="Some other item"></td>
<td><input type="text" name="quantity" value="2"></td>
<td>$10.00 <input type="hidden" name="price" value="10.00"></td>
<td align="right">$20.00<input type="hidden" name="sub_total" value="20.00"></td>
</tr>
</table>
<input type="submit" ...>
</form>
Problem is... you now have two fields named "itemindex", two named "quantity", two named "price", and so on.
GET and POST allow for this, but what actually ends up happening is that both the values get posted in a single variable as a comma-delimited list. So, in ColdFusion terms, #FORM.itemIndex# is going to contain "1,2", #FORM.item# is going to contain "Some item,Some other item", #FORM.Price# will contain "5.00,10.00", etc.
So, in order to solve your issue, you would either a) have to figure out how to name all the fields uniquely, or b) have to figure out how to parse the values on your action page. A) is the most reliable, because, believe it or not, the HTML spec does not declare in what order the items should be added to the variable list... so you could end up with #FORM.item# equal to "Some item,Some other item", while #FORM.Price# equals "10.00,5.00" (prices are in the wrong order). Most browsers follow the "first in" rule... but that can't be trusted 100%. Unfortunately, A) is a bit more complicated.
The way I've done it in the past is something like:
Code:
<form action="IreallyShouldHaveApagenameHere!" method="post">
<table>
<cfloop from="1" to="#ArrayLen(session.MyCart)#" index="i">
<cfoutput>
<tr>
<td>#session.MyCart[i].itemname#<input type="hidden" name="item_#i#" value="#session.mycart[i].itemname#"></td>
<td><input type="text" name="quantity_#i#" value="#session.mycart[i].quantity#" size="3" maxlength="3" style="font: smaller;"></td>
<td>#DollarFormat(session.mycart[i].price)#<input type="hidden" name="price_#i#" value="#session.mycart[i].price#"></td>
<td align="right">#DollarFormat(session.mycart[i].sub_total)#<input type="hidden" name="sub_total_#i#" value="#session.mycart[i].sub_total#"></td>
</tr>
</cfloop>
</table>
<input type="hidden" name="itemQty" value="#ArrayLen(session.MyCart)#">
<input type="submit" ...>
What this does is name the fields "price_1", "price_2", "quantity_1", "quantity_2", and so on.
Then, the action page can do something like:
Code:
<cfif NOT IsDefined("session.MyCart")>
<cfset session.MyCart = ArrayNew(1)>
<cfset temp = ArraySet(session.MyCart, 1,1,"")>
<cfelse>
<!--- since you'll be recreating the array each time,
you should clear the existing one --->
<cfset temp = ArrayClear(session.MyCart)>
</cfif>
<cfloop index="i" from="1" to="#FORM.itemQty#">
<CFSET tempStruct = StructNew()>
<cfset temp = StructInsert(tempStruct, "item", form["item_#i#"])>
<cfset temp = StructInsert(tempStruct, "itemname", form["itemname_#i#"])><cfset temp = StructInsert(tempStruct, "quantity", form["quantity_#i#"])>
<cfset temp = StructInsert(tempStruct, "price", form["price_#i#"])>
<cfset temp = StructInsert(tempStruct, "sub_total", form["sub_total_#i#"])>
<CFSET temp = ArrayAppend(Session.MyCart, Duplicate(tempStruct))>
<CFSET temp = StructClear(tempStruct)>
</cfloop>
Hope it helps.
-Carl