Wednesday 13 May 2009

More shopping cart (cowbell!)

Right our little shopping cart demo is starting to take shape and look ok.

But there is some issues with it.

  • You cannot update the amount in the cart
  • Adding existing items changes the order of the cart
  • Some repeated code

So lets do some changes.

To add the an update to the cart items, we need a text box that we can update.

In the repeater _Cart we need to change the amount row to

<asp:TextBox ID="_Amount" runat="server" Text="<%# ((CartItem)Container.DataItem).Amount.ToString(CultureInfo.InvariantCulture) %>"></asp:TextBox>

This wraps the Amount value in a textbox and sets the text to the current amount.

So if we build and view it in the browser we now have a nice textbox in our shopping cart

NewTextBox

But we now also have to add some code to handle this in the code behind. In the repeater item event handler for _Cart we will need to add some changes.

private void CartItemCommand(object source, RepeaterCommandEventArgs e)
       {
           if (Session["Cart"] == null) return; //No session just return

           //Check what button was pressed and do stuff

           switch (e.CommandName)
           {
               case "Remove":
                   {
                       var cartItems = (List<CartItem>)Session["Cart"];
                       //since the session is a controlled list, just remove at the index
                       cartItems.RemoveAt(e.Item.ItemIndex);
                       //Assign back to session
                       UpdateSessionAndLabels(cartItems);
                   }
                   break;
               case "Update":
                   {
                       var amount = (TextBox)e.Item.FindControl("_Amount");

                       int intAmount;
                       Int32.TryParse(amount.Text, out intAmount);//will set the value to 0 if cannot parse
                       var cartItems = (List<CartItem>)Session["Cart"];
                       cartItems[e.Item.ItemIndex].Amount = intAmount;
                       UpdateSessionAndLabels(cartItems);
                   }
                   break;
           }

       }

First we check to see if we have the cart in session and then do a switch statement on CommandName so that we can determine what we need to do. So in the Update method, we look for the control _Amount which is our TextBox and cast it as such.

We need to set the value of the Amount and first you should try and make sure its an integer.

Also there is a function UpdateSessionAndLabels which manages putting the cart back into session and rebinding the Cart

private void UpdateSessionAndLabels(List<CartItem> cartItems)
        {
            Session["Cart"] = cartItems;
            _totalPrice = 0;
            _numItems = 0;
            cartItems.ForEach(GetTotalPrice);
            _CartSize.Text = _numItems.ToString();
            _FullPrice.Text = _totalPrice.ToString();
            BindCart();
        }

This just makes life easier because we dont need to repeat as much code.

Right now we can update the amount in our shopping cart. Lets take a look at the changing order when we add existing products.

var hasitem = cartItems.Find((ci => ci.Id == cartItem.Id));
            //If the item exists, get its current amount and add 1.
            if (hasitem != null)
            {  
                cartItems[cartItems.IndexOf(hasitem)].Amount+=1;
            }
            else
            {
                cartItem.Amount = 1;
                cartItems.Add(cartItem);
            }
            //put the cart back into the session state
            UpdateSessionAndLabels(cartItems);

We need to see if the item exists still. But now we just access it by the index and update the amount. Otherwise set the value to 1 and add it to the list.

A little bit of a tidy up and some extra functionality to this demo

You can download the code from here

No comments: