hbradshaw has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks, This is probably a very easy problem to solve. I just can't see right off what's causing it.
Here's the deal...I have a scalar variable called color which contains three colors: red, white, blue. I want to split this variable so I can have a popup menu showing the colors as a list. So far, no problem there.
The code I wrote for the split and the popup menus is:
@color = split (/,/, $ref->{color}); td ({-colspan => "3", -align => "right"}, "Colors:", popup_menu( -name + => "color", -values => \@color))),
Well, I need to pass the color choice into a shopping cart. When I go to view the shopping cart, I receive a table that shows the following:
Item 7 ; quantity 1; color blue, price 5.69
item_id; quantity 1; color blank, price blank
I'm not sure why I put an item into my shopping cart, the item appears twice.
I've included all the code being used to prepare the view cart.
Here's the code for selecting the items to add to the cart:
sub get_product_table { my $sth = shift; my @row; my @nav_link; my @color; while (my $ref = $sth->fetchrow_hashref ()) { my $serve_url = sprintf ("serve_image.cgi?item_id=%s;picture", es +cape ($ref->{item_id})); @color = split (/,/, $ref->{color}); # generate a form allowing a quantity of the item to be added # to the cart push (@row, start_form(-method=>'POST', -action=>url()), hidden( -name => "choice", -override => 1, -default => "add" ), hidden( -name => "item_id", -override => 1, -default => escapeHTML($ref->{item_id})), Tr ({-style=>"font-family: verdana; font-size: 10pt;"}, td (img ({-src => $serve_url, -alt => escapeHTML($ref->{item_id})}) +), td ({-width=>"80", -valign=>"top", -align => "center"}, escapeHTML( + $ref->{item_id} )), td ({-width=>"190", -valign=>"top"}, escapeHTML( $ref->{description +} ))), td (" "), Tr ({-style=>"font-family: verdana; font-size: 10pt;"}, td ({-colspan => "3", -align => "right", -style=>"font-weight: 700; + color:blue;"}, "Price: \$", escapeHTML( sprintf( "%.2f", $ref->{pri +ce}))), Tr ({-style=>"font-family: verdana; font-size: 10pt;"}, td ({-colspan => "3", -align => "right"}, "Colors:", popup_menu( -n +ame => "color", -values => \@color))), Tr ({-style=>"font-family: verdana; font-size: 10pt;"}, td ({-colspan => "3", -align => "right"}, "Quantity:", popup_menu( +-name => "quantity", -values => ["1", "2", "3", "4", "5", "6", "7", " +8", "9"])), td (image_button( -name => "Add Item", -src=>"../images/add.jpg", - +border=>"0" )))), Tr ({-valign=>"top"}, td ({-colspan=>"7", -width=>"100%"}, hr)), end_form() ); } $sth->finish (); return undef unless @row; # no items? return (table ({-border => 0, -align => "center", -style=>"font-fa +mily: verdana; font-size: 10pt;"}, @row)); }
Here's the add item subroutine...
sub add_item { my ($dbh, $cart_ref, $item_id, $qty, $color) = @_; # If the item isn't already in the cart, look it up from the datab +ase # and store it in the cart as a new entry with a quantity of zero. if (!exists ($cart_ref->{$item_id})) { my $sth = $dbh->prepare ("SELECT * FROM catalog_pet WHERE item_id = ?"); $sth->execute ($item_id); my $item_ref = $sth->fetchrow_hashref (); $sth->finish (); return if !defined ($item_ref); # this shouldn't happen... $cart_ref->{$item_id} = {}; # create new entry, indexed by +item ID $cart_ref->{$item_id}->{description} = $item_ref->{description +}; $cart_ref->{$item_id}->{price} = $item +_ref->{price}; $cart_ref->{$item_id}->{qty} = 1; } $cart_ref->{item_id}->{qty} = $qty; $cart_ref->{$item_id}->{color} = $color; }
Finally, here's the code for viewing the cart.
sub format_cart_html { my ($cart_ref, $show_links) = @_; my $total_price = 0; my @row; my @color; if (!keys (%{$cart_ref})) { return (p ("Shopping cart is empty.")); } $page .= h3 ({-align=>"center", -style=>"font-family: +verdana; font-size: 16pt; color: blue;"}, ("Shopping Cart")); push (@row, Tr ({-align => "CENTER", -valign=>"TOP", -BGCOLOR=>" +silver", -style=>"font-family: verdana; font-size: 10pt;"}, th ({-width=>"80"},("Item")), th ({-width=>"50"},("Qty")), th ({ +-width=>"94"},("Color")), th ({-width=>"190"},("Description")), th ({-width=>"94"},("Unit Price")), th ({-width=>"94"},("Price")) )); foreach my $item_id (sort (keys (%{$cart_ref}))) { my $item_ref = $cart_ref->{$item_id}; my $total_item_price = $item_ref->{qty} * $item_ref->{price}; $total_price += $total_item_price; # generate a link allowing the item to be deleted from the car +t my $url = sprintf ("%s?choice=delete;item_id=%s", url (), escape ($item_id)); push (@row, start_form(-method=>'GET', + -action=>url()), hidden( -name => "choice", -override => 1, -default => "update" ), hidden( -name => "item_id", -override => 1, -default => escapeHTML( $i +tem_id )), Tr ({-valign=>"center", -style=>"font-f +amily: verdana; font-size: 10pt;"}, td ({-align => "center"},(escapeHTML ($ +item_id))), td ({-align => "center"},( textfield( - +name => "quantity", -size => "1", -override => 1, -value => $item_ref +->{qty}))), td (escapeHTML ($item_ref->{color})), td (escapeHTML ($item_ref->{description})), td ({-align => "right"}, escapeHTML (sp +rintf ("%.2f", $item_ref->{price}))), td ({-align => "right"}, escapeHTML (sprintf ("%.2f +", $total_item_price))), td (a ({-href => $url}, img ({-src => ".. +/images/delete1.jpg", -border => "0"}))), td (image_button( -name => "update", -src +=>"../images/update1.jpg", -border=>"0" )), end_form() )); } push (@row, Tr ({-align => "CENTER", -valign=>"center", -style=>" +font-family: verdana; font-size: 10pt;"}, td ({-colspan => "2"}, ""), td ({-colspan => "2", -align=>"right", -style=>"font-w +eight: 700;"}, "Total"), td ({-align => "right", -style=>"font-weight: 700;"}, escapeHTML (sprintf ("%.2f", $total_price))) )); return (table ({-align => "CENTER", -border => 0}, @row)); }
Any help you can give me in eliminating the second bogus entry will be great. Thank you.

update (broquaint): added <readmore> tag

Replies are listed 'Best First'.
Re: Splitting a scalar variable problem
by poj (Abbot) on Feb 18, 2003 at 18:07 UTC
    In the add item routine
    .. $cart_ref->{$item_id}->{qty} = 1; } ## $cart_ref->{item_id}->{qty} = $qty; ## missing $ $cart_ref->{$item_id}->{qty} = $qty; # correct $cart_ref->{$item_id}->{color} = $color;
    poj
      Poj, Hi! Thanks for the help. The missing $ was definately the problem. Thanks again.
      Poj, Hi.

      I made another modification to my code. Instead of having a popup menu, I changed to a multiple scroll list. So, people can choose more than one color.

      When I try to select to select multiple colors for an item, only the first color of the list appears in the cart.

      Here is the modified code for the multiple scroll list...

      td ({-colspan => "3", -align => "right"}, "Colors:", scrolling_list( - +name => "color", -size => 2, -multiple => 1, -values => \@color))),
      This is the only change I made to the code. Can you give me a hand in figuring out why choosing more than one color results in printing of only one color? The rest of the code is in the original node. Thanks for your help.
      Poj, Good Morning....

      Please disregard my last entry to this node about selecting multiple items.

      I want to go another way. I would like to have a person place an item in the cart with one color and then place the same item in the cart with another item. The result in the view cart would be an item appearing twice but with different color entries.

      Right now, my code does not allow that. If I place an item in the cart with a color and try to place the same item with a different color, the previous choice is updated. My cart only shows the item once with the most recent color chosen.

      Would you have any thoughts on how I can fix my code to accomplish my goal? All the code is still in this node that deals with adding items to the cart. Thanks for your help.
      + you da man! :)
Re: Splitting a scalar variable problem
by JamesNC (Chaplain) on Feb 18, 2003 at 17:57 UTC
    momma mia... I will have another meatball with my speghetti..
    I think your need to look at your hidden input items to see why you are getting that extra item in your form. Perhaps you aren't testing them for default values and they are being passed along with the other form data when it posts. If it is a parsing problem, I couldn't tell without having access to your DB. It looks like your problem is with your hidden or default values :) Ciao! James