tags:

views:

548

answers:

3

I have a shopping cart where the following are true:

  • There is one "Remove" button for each product in the shopping cart
  • There is one editable quantity text box for each product in the shopping cart
  • There is one "Update" button for the entire shopping cart

The idea is that the user can modify the quantities for each product in the cart and click "Update" to commit the changes.

How would you program the "Update" button using MVC? Would you wrap the entire shopping cart in a form that posts back to itself and somehow locate the quantity values in the FormCollection? The problem with that approach is that since the "Remove" buttons each live in their own forms I would now be doing nested forms on the page and I am not even sure that is allowed.

Any help would be appreciated.

Thanks

     <% using (Html.BeginForm("Index", "Cart")) { %> 
        <table>
   <tr>
    <th>&nbsp;</th>
   </tr>
     <% foreach (var item in Model) { %>
   <tr>
    <td>
        <input name="qty" type="text" value="<%=item.Quantity%>" maxlength="2" />
        <% using (Html.BeginForm("RemoveOrderItem", "Cart")) { %>            
            <%= Html.Hidden("ShoppingCartItemID", item.ShoppingCartItemID) %>
            <input name="add" type="submit" value="Remove" />
        <%} %>
    </td>
   </tr>
     <% } %>
  </table>

  <input name="update" type="submit" value="Update" />
        <%} %>

How would I incorporate the bottom input into this form?

+3  A: 

Nested forms are explicitly not supported in HTML.

You can however have multiple forms, this is allowed. Wrap each product in a separate form, add a product-specific parameter to each form post url so that you know in the respective controller action which product needs to be updated.

Something like this:

<form action="/update/21342345">
</form>

How would I incorporate the bottom input into this form?

Two options:

  1. Give each form its own submit button. Call it something like "Update this product". You will specify which one to update in the url parameter.
  2. Wrap you complete generated table along with the submit button into one single form. When submitted, you will need to update all of the products contained in the form. or somehow detect which ones were changes and only update those.

Advice applies to both buttons, submit and delete. You can specify the task in the post url, like:

action="/update/21342345"

or

action="/delete/21342345"
Developer Art
A: 

We've done this on our project by using an individual form for Remove, and a completely different form for Update. They both go to different POST actions in the CartController.

UPDATE: Example given (in raw HTML):

<form action="/cart/updatequantity" method="post"> 
 <input type="hidden" name="ProductSku" value="ABC-123" /> 
 <input name="quantity" class="quantity" size="2" maxlength="2" type="text" value="1" /> 
 <input type="submit" value="Update" /> 
</form> 

<form action="/cart/removeitem" method="post"> 
 <input type="hidden" name="productSku" value="ABC-123" /> 
 <input type="submit" value="Remove" /> 
</form>
Chris Missal
If that's not clear... Not nested, just next to each other.
Chris Missal
Can you give an example? I only have one Update button at the bottom of the page and the textboxes containing the quantities is on the item level. How do you form this correctly?
Thomas
+1  A: 

I am using jQuery in similar situation. Remove button calls post() method and if it succeeds, div element of this product is removed from page (remove() method). Update can be submit of normal form. you can also use jQuery to program ajax Update method and then load shopping cart dynamically, without having to reload whole page (by $().html() method called in callback of post()).

Remove could look like:

onclick="if (confirm('Please confirm.')) $.post('/Cart/Remove/63',{},function(data) { if (data == 'ok') {$('#cart-element-63').remove())";

LukLed