PDA

View Full Version : Doubling up on inputs


mpwright
10-19-2004, 04:09 AM
Hi,

Ive just moved into a new job & have been asked to modify a asp shopping cart site. Im having a problem where when I have more than one item in the shopping basket & try to update the quantities, it freezes the browser. I asked a few questions on an ASP forum & got some good advice, but the following post has left me a bit stumped as I only have some very basic html knowledge. Below is what another user has told me to do:

"You have a doubled up form input on the previous page. Anytime you get multiple values for a single input when your expecting only one value it means you have two inputs with the same name. This will cause them to get poassed as a comma-space delimited string.

I agree that you should add some isNumeric validation on the server side, but you need to go back to the previous page first and figure out why there are two inputs with the same name and get rid of the offending one that is passing the extra (unnecessary) value."

So my question is, how do I modify the HTML code to not double up on inputs, the code im using is below:

<%



Recentpage = (request.cookies("recentpage"))

if request.cookies("modified") = "true" then
reloadpage = "default.asp"
target="_parent"
else
reloadpage = "prodetails.asp"
target="main"
end if

%>

<html>
<head>
<SCRIPT LANGUAGE="JavaScript">
<!-- hide JS code
var justValidating = true
function validateForm(f){
var val = f.item.value;
if(/^\d{1,}$/.test(val)){
return true;
}else{
f.item.focus;
alert('Invalid Input for quantity');
return false;
}

}


// end JS hide -->
</SCRIPT>
</head>
<body bgcolor="#FFFFFF" vlink="blue"><form METHOD="get" ACTION="qtyupd.asp" target="_parent" onsubmit="return validateForm(this)">
<div align="center">
<table width="100%" border="0" cellspacing="0" cellpadding="0" height="100%">
<tr valign="top">
<td height="95%">
<div align="center">
<p><font size="5"><b><font face="Arial, Helvetica, sans-serif">Your
Shopping Cart</font></b></font></p>
<p>&nbsp;</p>
</div>
<table width="550" border="1" align="center" bordercolor="#000000" cellspacing="0" height="55">
<tr bgcolor="#333366">
<td height="25">
<table width="100%" border="0" cellspacing="0">
<tr>
<td width="310"><font size="2"><b><font face=Arial color=#FFFFFF>&nbsp;Item
Name</font></b></font></td>
<td width="90">
<div align="center"><font size="2"><b><font face=Arial color=#FFFFFF>Unit
Price</font></b></font></div>
</td>
<td width="32">
<div align="center"><font size="2"><b><font face=Arial color=#FFFFFF>Qty.</font></b></font></div>
</td>
<td width="110">
<div align="center"><font size="2"><b><font face=Arial color=#FFFFFF>Extended
Price</font></b></font></div>
</td>
</tr>
</table>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td height="25">
<table cellpadding=4 border=0 cellspacing=0 width='550' align="center">
<%

Set conn = Server.CreateObject("ADODB.Connection")
Conn.Open ("driver={Microsoft Access Driver (*.mdb)};DBQ=" & server.mappath("aspcart5.mdb"))

sql = "SELECT * FROM temporary where custid = '" & Request.Cookies("customerid") & "' ORDER BY item;"
set rs = Conn.Execute(sql)

do while not rs.eof

spaceditem = Replace((rs("item"))," ","+")

runningtotal = runningtotal + rs("unitprice") * rs("quantity")
runningqty = runningqty + rs("quantity") * 1

stripped = Replace(rs("item"),"_"," ")
secondstripped = Replace(stripped,"^","'")
%>
<tr>
<td bgcolor=#FFFFFF width="46%"><font face="Arial, Helvetica, sans-serif" size="2"><a href="reverseget.asp?reverseget=<%=secondstripped%>&start=1"><%=secondstripped%></a></font></td>
<td bgcolor=#FFFFFF width="11%"> <font face="Arial, Helvetica, sans-serif" size="2"><a href="delitem.asp?item=<%=rs("item")%>" target="_parent"><img src="delete.jpg" height="15" vspace="0" hspace="0" border="0"></a>
</font></td>
<td align=RIGHT bgcolor=#FFFFFF width="17%">
<div align="center"><font face="Arial, Helvetica, sans-serif" size="2"><%=FormatCurrency(rs("unitprice"))%></font></div>
</td>
<td align=RIGHT bgcolor=#FFFFFF width="6%">
<div align="center"><font face="Arial, Helvetica, sans-serif" size="2">
<input size=2 maxlength=5 name="item" value="<%=rs("quantity")%>">
</font></div>
</td>
<td align=RIGHT bgcolor=#FFFFFF width="20%">
<div align="center"><font face="Arial, Helvetica, sans-serif" size="2"><%=FormatCurrency(rs("quantity") * rs("unitprice"))%></font></div>
</td>
</tr>
<%
rs.movenext
loop
rs.close

If runningtotal = 0 then %>
<tr>
<td align='LEFT' colspan='5' gcolor='#EEEEEE' height="2" bgcolor="#CCCCCC">
<div align="center"><b><font face="Arial, Helvetica, sans-serif">Your
Shopping Cart is Empty</font></b></div>
</td>
</tr>
<% End if %>
<tr bgcolor="#CCCCCC">
<td align='LEFT' colspan='3' gcolor='#EEEEEE' height="33" bgcolor="#FFFFFF"><font face="Arial, Helvetica, sans-serif" size="2"><b>Total,
Less Tax and Shipping &amp; Handling:</b></font></td>
<td align='RIGHT' width="6%" height="33">
<div align="center"><b><font face="Arial, Helvetica, sans-serif" size="2" color="#000000"><%=runningqty%></font></b></div>
</td>
<td align='RIGHT' width="20%" height="33">
<div align="center"><b><font face="Arial, Helvetica, sans-serif" size="2" color="#000000"><%=FormatCurrency(runningtotal)%>&nbsp;</font></b></div>
</td>
</tr>
</table>
</td>
</tr>
</table>
<div align="center">
<p>&nbsp;</p>
<table width="400" border="0" cellspacing="0" cellpadding="0">
<tr>
<td>
<div align="center"><a href="continue.asp?prodid=<%=Request.Cookies("lastprod")%>" target="_parent"><img src="return.gif" alt="CONTINUE SHOPPING" border="0" width="93" height="35"></a></div>
</td>
<td>
<div align="center">
<input type="IMAGE" src="update.gif" border="0" name="UPDATE QUANTITIES" width="93" height="35">
</div>
</td>
<td>
<div align="center"><a href="emptycart.asp" target="_parent"><img src="clear.gif" alt="EMPTY CART" border="0" width="93" height="35"></a></div>
</td>
<td>
<div align="center"><a href="checkout.asp"><img src="checkout.gif" alt="CHECKOUT" border="0" width="93" height="35"></a></div>
</td>
</tr>
</table>
</div>

</form>
</body></html>

Any advice would be greatly appriciated.

Kind Regards

Mark

eRad
10-19-2004, 08:52 AM
if i am reading your code correctly, the input in question is
<input size=2 maxlength=5 name="item" value="<%=rs("quantity")%>">

these inputs are created multiple times as you loop through each item in the recordset, right?

well if that's the case - you will have all your inputs have the same name, 'item'

i think what you should do to solve this is append the index of the item onto the end of the name... that way each one created will have a unique name.

something like this maybe..
<input size=2 maxlength=5 name="item<%=rs("itemID")%>" value="<%=rs("quantity")%>">

note: access has probably created an index (primary key) field for you - if so it will be called ID. If you mapped a primary key yourself then use that field instead.

mpwright
10-19-2004, 09:26 AM
Hi,

Thanks for that, Ive ammended the line that you said but I now get the error:

Error Type:
ADODB.Recordset (0x800A0CC1)
Item cannot be found in the collection corresponding to the requested name or ordinal.
/asp/viewcart.asp, line 100

Now im totally new to ASP, have barely looked at access & only have a bit of HTML knowledge, but am I right in assuming that error is generated because of what you said about the Primary Key? Ive had a look in access design view to see if I can see what the Primary Key is associated to but there is not one there?

Once again, many thanks for your help

Mark

eRad
10-19-2004, 09:41 AM
Well that's probably because it couldn't find the field i gave as an example 'itemID'

like i said it probably is named 'ID'.. so you can try using that instead..

A database doesn't have to have a primary key but it always is good to have one. Look at all the fields in your table and see if any of them has a little key beside them. If not, pick a field that has every single entry unique (if your table has some sort of item ID or item number field..), and click the key button in your toolbar to make it a primary key. You can now use this field in place of the itemID.

If you don't have any usable unique fields, you'll have to create a new one. The thing is the ID field has to be autonumbered, and in Access if you added one, it wouldn't fill in the numbers for all your prior entries... What you would have to do is create a new table with the same structure as the one you have, except this time add an ID field. This can be done with the following steps (ignore all this if you already have a primary key field):
- Copy your existing table
- Paste the new table but select Import Structure Only
- Go to the new table's design view and add your ID field, set it to AutoNumber
- Go to your old table, select and copy all your records
- Go to the new one, and paste.
The autonumber field will generate all the numbers itself when you paste. Now you have a unique ID field which you can refer to in the place of that 'itemID'.

Hope that helps.

mpwright
10-19-2004, 10:39 AM
Thanks for that, the website now allows me to add items to the cart without a problem, but when I try to update the quantities i get a popup saying invalid quantity. It looks like there is some kind of javascript valadation in there that doing this? Any ideas?

Ive checked the database & there dosent seem to be a primary key set, however there is an field called item, which I assume is what needs to be the primary key? But when I assign it to be the primary key & try to save the file I get the picture that is attached. From what I can make out it looks like there may be a primary key already assigned but upon checking through the entire database i cant see one.

eRad
10-19-2004, 10:52 AM
Yes, your code has a validation on the quantity. I'm not sure exactly what that does... you'd have to ask a real javascript pro on this forum

<SCRIPT LANGUAGE="JavaScript">
<!-- hide JS code
var justValidating = true
function validateForm(f){
var val = f.item.value;
if(/^\d{1,}$/.test(val)){
return true;
}else{
f.item.focus;
alert('Invalid Input for quantity');
return false;
}

}
// end JS hide -->
</SCRIPT>

frankly the only validation i can imagine you'd want to do is check if it's a number, which can be accomplished by simply doing this instead:

<SCRIPT LANGUAGE="JavaScript">
<!-- hide JS code
var justValidating = true
function validateForm(f)
{
var val = f.item.value;
if (isNaN(val))
{
f.item.focus;
alert('Invalid Input for quantity');
return false;
}
else{ return true; }
}
// end JS hide -->
</SCRIPT>


As for the access issue - the reason it is preventing you from setting the primary key is because the items field has duplicate entries - so it cannot be used as a primary field. There is a field there that looks appropriate - 'prodid'.. it says it is a unique ID for the item. Try assigning that as a the primary key, and using that as the 'itemID' field in the code instead.

mpwright
10-19-2004, 11:15 AM
still no joy im afraid, using "prodid" as the primary key and using the line of code:

<input size=2 maxlength=5 name="item<%=rs("prodid")%>" value="<%=rs("quantity")%>">

I also tried

<input size=2 maxlength=5 name="prodid<%=rs("prodid")%>" value="<%=rs("quantity")%>">

I get:

Error Type:
ADODB.Recordset (0x800A0CC1)
Item cannot be found in the collection corresponding to the requested name or ordinal.
/asp/viewcart.asp, line 100

eRad
10-19-2004, 11:26 AM
it seems you have more than one table...

how many do you have? your ASP recordset is actually querying the table titled 'temporary', and not the 'products' table shown in the picture

that table has different fields... for example the products table doesn't have a quantity field, but the other one probably does.

try and do the same thing you do to this other 'temporary' table - which is the one you should be working with i think

mpwright
10-19-2004, 11:39 AM
Your right, the temporary table does have a field called quantity, whilst the other one dosent. But when I alter the code to look in the "temporary" field instead of the other I get:

Error Type:
ADODB.Recordset (0x800A0CC1)
Item cannot be found in the collection corresponding to the requested name or ordinal.
/asp/viewcart.asp, line 100

Would I be able to send you my database so you could have a look to see if I have it set correctly?

Many Thanks for your time & help so far

Mark

eRad
10-19-2004, 11:48 AM
Originally posted by mpwright
Your right, the temporary table does have a field called quantity, whilst the other one dosent. But when I alter the code to look in the "temporary" field instead of the other I get:

Error Type:
ADODB.Recordset (0x800A0CC1)
Item cannot be found in the collection corresponding to the requested name or ordinal.
/asp/viewcart.asp, line 100

Would I be able to send you my database so you could have a look to see if I have it set correctly?

Many Thanks for your time & help so far

Mark
Yes. Check your PMs.

mpwright
10-19-2004, 12:41 PM
Thanks, sending across now

eRad
10-19-2004, 02:04 PM
Ok after some careful analysis of your entire application (hehe... somewhat of a mess ;)) i realized that the temporary is just some kind of dump he has created for items ordered recently. That or it's a testing table, i think it's intended to be a sort of Requisitions table which will hold all orders, since each entry has a unique CUSTOMER id. Anyway, the loop generates all the entries that match the current customer (which is retrieved via a cookie), there is no need to utilize an ID field. Any simple counter variable should suffice.

So before the 'do while not rs.eof' add a line that initializes the counter:
Dim counter As Integer = 0
and then after rs.movenext (right before Loop) place a line that says:
counter += 1

I saw you already replaced that itemID with 'counter' so that should be all you need. I tried to run this myself but nothing seems to be working properly, there must be some other files/settings on your side that make it work.

mpwright
10-19-2004, 02:14 PM
It looks like a hell of a mess dont it!
Thanks for taking the time to look at it. Right, Ive added the code you said, this is what I have added to the file addcart.asp:

Dim counter As Integer = 0
do while not rs.eof

If rs("item") = CUSTitem then Foundit = "Yes"
rs.movenext
counter += 1

loop

When I try to add something to the cart though I get:

HTTP 500 - Internal server error
Internet Explorer

eRad
10-19-2004, 02:33 PM
Originally posted by mpwright
I get:

HTTP 500 - Internal server error
Internet Explorer
adding seems to be working just fine for me... that is usually caused by a timeout. just try again.

also.. how are you viewing the site?

if it's stored on your hard drive then you need to use IIS to view it locally - or are you uploading to a server everytime?

P.S. Remember to change the javascript to what i told you - i dunno what function was there but it certainly isn't working right.

mpwright
10-19-2004, 03:23 PM
Hmm it must be something with my PC at home? Im using IIS here, but I'll give it a try tommorow on my laptop at work, I'll let you know how it goes...thanks for your help so far! I really appreciate it.

Regards

Mark

eRad
10-19-2004, 03:32 PM
Np :)

Hopefully works tomorrow.

mpwright
10-20-2004, 04:11 AM
Hi again,

Ok just got to work and tried it, it dosent freeze the browser like at home, but when I try to add to the cart I get:

Error Type:
Microsoft VBScript compilation (0x800A0401)
Expected end of statement
/asp/addcart.asp, line 58, column 12
Dim counter As Integer = 0;

thats using the line:
<input size=2 maxlength=5 name="item<%=rs("item")%>" value="<%=rs("quantity")%>">

In viewcart.asp

and

Dim counter As Integer = 0

do while not rs.eof

If rs("item") = CUSTitem then Foundit = "Yes"
rs.movenext

counter += 1

loop

In addcart.asp

Many Thanks

Mark

eRad
10-20-2004, 08:54 AM
Bah you changed it back hehe =P, and i gave you a little syntax wrong (sorry i've been doing too much .NET)

for viewcart.asp make it:
counter = 0
do while not rs.eof

...

<input size=2 maxlength=5 name="item<%=counter%>" value="<%=rs("quantity")%>">

...

rs.movenext
counter = counter + 1
loop


for addcart.asp:
I don't know why you added the counter to this file (or was it already there?) - but my file does not have a Dim counter As Integer = 0 declaration - only a counter = 0 declaration. Anyhow you can remove the counter completely for addcart.asp... it is never referred to elsewhere... so make that code section just
do while not rs.eof
If rs("item") = CUSTitem then Foundit = "Yes"
rs.movenext
loop


If you are still having problems i'll just send you the files i have, they are working perfectly and the only changes i made were adding the counter and fixing the javascript.

mpwright
10-20-2004, 08:59 AM
hmm I must still have something wrong in my code somewhere as it still wont work, would you be able to send me the files you have please.....thanks very much

Mark :)

eRad
10-20-2004, 09:35 AM
Yes, i am sending them now...

I also took the liberty of writing you a better (read: working) javascript function, the other one only checked one input and assumed it was named item... anyway here it is:

<script type="text/JavaScript">
function validateForm(f)
{
for (var i=0; i<f.elements.length; i++)
{
if(isNaN(document.getElementById('item'+i).Value))
{
alert("Invalid Quantity on item " + i);
}
}
else
{ return true; }
}
</script>

This works.. but what your application does upon a quantity change is *interesting* to say the least.

Also... the author of this decided he would never close any connections... *very bad*

Add the following lines in ALL of your ASP pages whenever you are done with a recordset/connection:

rs.close
conn.close
set rs = nothing
set conn = nothing

There are quite a few bugs with the program but to go any further would be doing your job ;).

Good luck.

mpwright
10-20-2004, 10:05 AM
cool, it nows add's a treat, thanks very much!!!! and thanks for doing the improved script.....do you have any idea why it empties the cart when updating or when adding an invalid number? Just some pointers as youve done more than enough for me this last couple of days.

Cheers

Mark

eRad
10-20-2004, 10:46 AM
The way it's setup is to use the onsubmit="validateForm(this)" call to validate after the form has already called a submit. That means it's going to submit regardless, it's only a question of whether values are being sent.

What you can try instead is to set the Update button's onClick value to call the validating function, instead of doing it in the onsubmit of the form. That way, if it validates, it will submit, otherwise, it will do nothing (except the alert).

mpwright
10-20-2004, 11:00 AM
hmmm I think i follow ya. Ok, i'll have a play & see what I can come up with. Thanks for all your help!

Kind Regards

Mark

mpwright
10-20-2004, 11:21 AM
Ive just noticed in the code you sent back to me when i view the cart the "page error" icon appears at the bottom and says:

Line: 15
Char: 2
Error: Syntax error
Code: 0
URL: http://localhost/asp/viewcart.asp

Could this be why it's not updating properly do you think? Ive changed the update button to call onclick rather than on submit but it still does the same, empty the cart.

Regards

Mark

eRad
10-20-2004, 11:22 AM
Originally posted by mpwright
hmmm I think i follow ya. Ok, i'll have a play & see what I can come up with. Thanks for all your help!

Kind Regards

Mark
Anytime.

Good Luck with the rest :)