Copy link to clipboard
Copied
Hi everyone. I was able to get a very simple shopping cart set up and to work with adding a Product to the cart and deleting the Product, but how do I add or display something such as the price of the product too? Here's what I have below on a products.cfm page and a ShoppingCart.cfm page:
products.cfm
<form action="ShoppingCart.cfm" method="post">
Product 1 Description
<input type="hidden" name="productID" value="1" />
<input type="hidden" name="productName" value="Socket" />
<input type="submit" value="Add To Cart" />
</form>
<form action="ShoppingCart.cfm" method="post">
Product 2 Description
<input type="hidden" name="productID" value="2" />
<input type="hidden" name="productName" value="Adapter" />
<input type="submit" value="Add To Cart" />
</form>
ShoppingCart.cfm
<cfif NOT StructKeyExists(session,'ShoppingCart')>
<cfset Session.ShoppingCart = StructNew()>
<cfset Session.ShoppingCart.FirstName = "">
<cfset Session.ShoppingCart.LastName = "">
<cfset Session.ShoppingCart.Address = "">
<cfset Session.ShoppingCart.Products = ArrayNew(2)>
</cfif>
<cfif StructKeyExists(form,'productID')>
<cfset Session.ShoppingCart.Products[arraylen(Session.ShoppingCart.Products)+1][1] = form.productID>
<cfset Session.ShoppingCart.Products[arraylen(Session.ShoppingCart.Products)][2] = form.productName>
</cfif>
<cfif StructKeyExists(url,'deleteID')>
<cfset variables.products = ArrayNew(2)>
<cfloop index="i" from="1" to="#arrayLen(Session.ShoppingCart.Products)#">
<cfif url.deleteID NEQ i>
<cfset variables.products[arraylen(variables.products)+1][1] = Session.ShoppingCart.Products[1]>
<cfset variables.products[arraylen(variables.products)][2] = Session.ShoppingCart.Products[2]>
</cfif>
</cfloop>
<cfset Session.ShoppingCart.Products = variables.products>
</cfif>
<cfif StructKeyExists(url,'editID')>
<cfset Session.ShoppingCart.Products[form.editID][1] = form.productID>
<cfset Session.ShoppingCart.Products[form.editID][2] = form.productName>
</cfif>
<cfoutput>
You have #arrayLen(Session.ShoppingCart.Products)# items in your cart.<br /><br />
<cfloop index="i" from="1" to="#arrayLen(Session.ShoppingCart.Products)#">
<table>
<tr>
<td>#Session.ShoppingCart.Products[2]#</td>
<td><a href="ShoppingCart.cfm?deleteID=#i#">Delete</a></td>
</tr>
</table>
</cfloop>
</cfoutput>
<br />
<form action="shopping.cfm" method="POST">
<div class="form-row">
<label>
<span>First Name</span>
<input type="text" size="20" name="FirstName">
</label>
</div>
<div class="form-row">
<label>
<span>Last Name</span>
<input type="text" size="20" name="LastName">
</label>
</div>
<div class="form-row">
<label>
<span>Address</span>
<input type="text" size="20" name="Address">
</label>
</div>
<input type="submit" class="submit" value="Check Out">
</form>
Thanks for your help.
Andy
Copy link to clipboard
Copied
jamie61880 wrote:
I was able to get a very simple shopping cart set up and to work with adding a Product to the cart and deleting the Product, but how do I add or display something such as the price of the product too?
The field names, productID and productName, tell you everything you need to know. Wherever there is code about productID and productName you should just add equivalent code about productPrice.
Hence,
<input type="hidden" name="productPrice">
<cfset Session.ShoppingCart.Products[arraylen(Session.ShoppingCart.Products)][3] = form.productPrice>
and so on. Remember to display the total price.
Copy link to clipboard
Copied
BKBK,
How do I display the price? I have the code below that outputs the ProductName with the [2], but the price doesn't output. I added the Price with [3] like you did above, but if I put this into the code below, I receive a 500 internal server error, that says:
"Error","ajp-bio-8014-exec-11","05/16/16","09:34:04","MySite","You have attempted to dereference a scalar variable of type class java.lang.String as a structure with members. The specific sequence of files included or processed is: D:\websites\Ironwoodelectronics\Sessions\Ben\ShoppingCart.cfm, line: 46 "
coldfusion.runtime.ScopeCastException: You have attempted to dereference a scalar variable of type class java.lang.String as a structure with members.
What does this error mean?
<cfoutput>
You have #arrayLen(Session.ShoppingCart.Products)# items in your cart.<br /><br />
<cfloop index="i" from="1" to="#arrayLen(Session.ShoppingCart.Products)#">
<table>
<tr>
<td>#Session.ShoppingCart.Products[2][3]#</td>
<td><a href="ShoppingCart.cfm?deleteID=#i#">Delete</a></td>
</tr>
</table>
</cfloop>
</cfoutput>
Andy
Copy link to clipboard
Copied
Which one is line 46?
In any case, you are attempting to use a three-dimensional array,
(Session.ShoppingCart.Products[2][3]),
whereas you had defined 2-D ones,
Session.ShoppingCart.Products[arraylen(Session.ShoppingCart.Products)][1],
Session.ShoppingCart.Products[arraylen(Session.ShoppingCart.Products)][2],
Session.ShoppingCart.Products[arraylen(Session.ShoppingCart.Products)][3],
etc.
I think the third one is the price.
Copy link to clipboard
Copied
This is line 46: <td>#Session.ShoppingCart.Products[2][3]#</td>
I have this at the top of the shopping cart page:
<cfif NOT StructKeyExists(session,'ShoppingCart')>
<cfset Session.ShoppingCart = StructNew()>
<cfset Session.ShoppingCart.FirstName = "">
<cfset Session.ShoppingCart.LastName = "">
<cfset Session.ShoppingCart.Address = "">
<cfset Session.ShoppingCart.Products = ArrayNew(2)>
</cfif>
I tried changing the ArrayNew(2) to a 3, but that didn't work either.Or does that not need to be changed? I don't understand why I can't get the price to output? I did everything same way as the ProductName.
Copy link to clipboard
Copied
jamie61880 wrote:
This is line 46: <td>#Session.ShoppingCart.Products[2][3]#</td>
Then my guess was correct. This code fails because it is a 3-D array, whereas your variables are 2-D.
I tried changing the ArrayNew(2) to a 3, but that didn't work either.
Just as well it didn't work. You want 2D (), not 3-D (
I suspect you might have confused the array indices right from the start. A natural design for product i would be as follows:
productID: Session.ShoppingCart.Products[1];
productName: Session.ShoppingCart.Products[2];
productPrice: Session.ShoppingCart.Products[3],
Take product 5, for example. Then youwill have
productID: Session.ShoppingCart.Products[5][1];
productName: Session.ShoppingCart.Products[5][2];
productPrice: Session.ShoppingCart.Products[5][3].
The last product added to the shopping-cart has index arraylen(Session.ShoppingCart.Products). Hence for this product,
productID: Session.ShoppingCart.Products[arraylen(Session.ShoppingCart.Products)][1];
productName: Session.ShoppingCart.Products[arraylen(Session.ShoppingCart.Products)][2];
productPrice: Session.ShoppingCart.Products[arraylen(Session.ShoppingCart.Products)][3].
Copy link to clipboard
Copied
Oh, and remember that the index of an array cannot be 0 in ColdFusion. So start by testing if arraylen(Session.ShoppingCart.Products) is greater than 0. That is, if the shopping-cart has at least one item.
Copy link to clipboard
Copied
BKBK,
Thank you! I finally got it to work correctly! I changed Price to Quantity, so the user could update the Quantity they want. How do you set up an Edit box for Quantity? I have this that puts the Quantity into a text box, but how do you update it so it updates the number the user could type in?:
<cfif StructKeyExists(url,'editID')>
<cfset Session.ShoppingCart.Products[form.editID][1] = form.productID>
<cfset Session.ShoppingCart.Products[form.editID][2] = form.productName>
<cfset Session.ShoppingCart.Products[form.editID][3] = form.productQuantity>
</cfif>
<td><cfinput type="text" name="#Session.ShoppingCart.Products[3]#" value="#Session.ShoppingCart.Products[3]#" passThrough = "readonly = 'True'"></td>
I've only ever updated a database, but not a session before.
Andy
Copy link to clipboard
Copied
jamie61880 wrote:
How do you set up an Edit box for Quantity? I have this that puts the Quantity into a text box, but how do you update it so it updates the number the user could type in?:
<td><cfinput type="text" name="#Session.ShoppingCart.Products[3]#" value="#Session.ShoppingCart.Products[3]#" passThrough = "readonly = 'True'"></td>
Just remove the readOnly attribute. If you know beforehand that the quanties will be within a small, specific range, then you could use a select-field for the Quantity.
Copy link to clipboard
Copied
BKBK,
Just removing the readonly attribute doesn't do anything. It doesn't update the text box after I change the quantity and click the Submit button. I did find this:
<cfif isDefined("Form.submit")>
<td>Quantity: <cfinput type="text" name="productQuantity" value="#productQuantity#"></td>
<cfelse>
<td><cfinput type="text" name="productQuantity" value="#Session.ShoppingCart.Products[3]#"></td>
</cfif>
One problem with this is after I click the Submit button when I have 12 items in the cart, this gets displayed in the text box for each line item: 1,1,1,1,1,1,1,1,1,9,1,1. 9 is the one I updated. How do I get this narrowed down to only having the one text box for the item I updated, display correctly. So that 9 is updated on Item 10 and the 1's are updated on all the other text boxes? Here's what I have for this whole output of code:
<cfoutput>
<cfform name="ShoppingCart" action="ShoppingCart.cfm" method="post">
You have #arrayLen(Session.ShoppingCart.Products)# items in your cart.<br /><br />
<cfloop index="i" from="1" to="#arrayLen(Session.ShoppingCart.Products)#">
<table>
<tr>
<td>#Session.ShoppingCart.Products[2]#</td>
<cfif isDefined("Form.submit")>
<td>Quantity: <cfinput type="text" name="productQuantity" value="#productQuantity#"></td>
<cfelse>
<td><cfinput type="text" name="productQuantity" value="#Session.ShoppingCart.Products[3]#"></td>
</cfif>
<td><a href="ShoppingCart.cfm?deleteID=#i#">Delete</a></td>
<td><input type="submit" name="submit" value="submit"></td>
</tr>
</table>
</cfloop>
</cfform>
</cfoutput>
Someone gave me this code for editing a shopping cart, but didn't show me how to use it. Do you know how to use this section otherwise?:
<cfif StructKeyExists(url,'editID')>
<cfset Session.ShoppingCart.Products[form.editID][1] = form.productID>
<cfset Session.ShoppingCart.Products[form.editID][2] = form.productName>
<cfset Session.ShoppingCart.Products[form.editID][3] = form.productQuantity>
</cfif>
Thanks.
Andy
Copy link to clipboard
Copied
The following code has just one named form-field. Therefore form.productQuantity will store all 12 quantities as a comma-delimited list.
<cfloop index="i" for="1" to="12">
<cfinput type="text" name="productQuantity">
</cfloop>
You could name the fields dynamically, for example, like this
<cfloop index="i" for="1" to="12">
<cfset currentFieldName = "productQuantity" & i>
<cfinput type="text" name="#currentFieldName#">
</cfloop>
<cfif StructKeyExists(url,'editID')>
<cfset Session.ShoppingCart.Products[form.editID][1] = form.productID>
<cfset Session.ShoppingCart.Products[form.editID][2] = form.productName>
<cfset Session.ShoppingCart.Products[form.editID][3] = form.productQuantity>
</cfif>
As your form uses Post instead of Get, I expected <cfif StructKeyExists(form,'editID')> instead.
Copy link to clipboard
Copied
BKBK,
Where do you put this line of code:
<cfloop index="i" for="1" to="12">
<cfset currentFieldName = "productQuantity" & i>
<cfinput type="text" name="#currentFieldName#">
</cfloop>
I was receiving an error that said there was an Attribute validation error for tag CFLOOP. The Valid Attributes are:
ARRAY,CHARACTERS,CHARSET,COLLECTION,CONDITION,DELIMITERS,ENDROW,FILE,FROM,GROUP,GROUPCASESENSITIVE,INDEX,ITEM,LIST,QUERY,STARTROW,STEP,TO
so I changed the For to From, and it went through, but it's still not working. Where do I put this loop? Above the CFOUTPUT, or inside the Form, or inside the IF isDefined("form.submit") line? I get different results where I put it. Does the text box you wrote in the code above, replace the text box I have? Or do I still need the IF isDefined("form.submit") statement and just use the text box you wrote above in this IF statement?
This is how I currently have everything:
<cfoutput>
<cfform name="ShoppingCart" action="ShoppingCart.cfm" method="post">
You have #arrayLen(Session.ShoppingCart.Products)# items in your cart.<br /><br />
<cfloop index="i" from="1" to="#arrayLen(Session.ShoppingCart.Products)#">
<table>
<tr>
<td>#Session.ShoppingCart.Products[2]#</td>
<cfif isDefined("Form.submit")>
<cfloop index="i" from="1" to="12">
<cfset currentFieldName = "productQuantity" & i>
</cfloop>
<cfinput type="text" name="#currentFieldName#" value="#currentFieldName#">
<cfelse>
<td><cfinput type="text" name="productQuantity" value="#Session.ShoppingCart.Products[3]#"></td>
</cfif>
<td><a href="ShoppingCart.cfm?deleteID=#i#">Delete</a></td>
<td><input type="submit" name="submit" value="submit"></td>
</tr>
</table>
</cfloop>
</cfform>
</cfoutput>
When I run this though, it just outputs "productQuantity12" into each text box. If I change the CFLOOP to this:
<cfloop index="i" from="1" to="#arrayLen(Session.ShoppingCart.Products)#">, it outputs "productQuantity8" into each text box since there are 8 items in my cart currently. The text box you wrote above did not have any value, so I was not able to see anything in the text box, so I added this: value="#currentFieldName#"
What am I still doing wrong?
Do I need to use this code at all? If so, how?
<cfif StructKeyExists(url,'editID')>
<cfset Session.ShoppingCart.Products[form.editID][1] = form.productID>
<cfset Session.ShoppingCart.Products[form.editID][2] = form.productName>
<cfset Session.ShoppingCart.Products[form.editID][3] = form.productQuantity>
</cfif>
Andy
Copy link to clipboard
Copied
jamie61880 wrote:
Where do you put this line of code:
<cfloop index="i" for="1" to="12">
<cfset currentFieldName = "productQuantity" & i>
<cfinput type="text" name="#currentFieldName#">
</cfloop>
That is pseudocode and has a typing error. Read instead: <cfloop index="i" from="1" to="12">. In any case, it assumes that you know the syntax and will make some judgements yourself.
The main message to pick out is the dynamic naming of the input field. Just take this idea back to your own code and apply it.
Do I need to use this code at all? If so, how?
<cfif StructKeyExists(url,'editID')>
<cfset Session.ShoppingCart.Products[form.editID][1] = form.productID>
<cfset Session.ShoppingCart.Products[form.editID][2] = form.productName>
<cfset Session.ShoppingCart.Products[form.editID][3] = form.productQuantity>
</cfif>
I have answered this already.