Hidden value for each item in List (MVC)

Viewed 1005

I'm trying to make some kind of a shopping cart, so I show a list of items in a view.

I added a submit button with the value "+ Add" and a number input with the value amount for each of the items displayed.

This is my code:
VIEW:

    @model MyProject.ViewModel.AddProductsViewModel
    
    @{
        Layout = null;
    }
    
    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()

    <table class="table" align="left" style="padding-left:15px">
        <tr>
            <th>
                Product
            </th>
        </tr>

        @foreach (var item in Model.ProductsList)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.Descripcion)
                </td>
                <td>
                    <input type="hidden" name="ProductId" value="@item.ProductId" />                                                                       
                    <input type="number" id="Amount" name="Amount"
                           min="1" max="30" value="1">
                    <input type="submit" value="+ Add" class="btn btn-primary" />
                </td>
            </tr>
        }
    </table>
}
 

MODEL:

  public class AddProductsViewModel
     {
            ...stuff here...
          
        public List<Products> ProductsList { get; set; }
     }

I need my controller to get the productId from the item I clicked submit to, but this way I'm only getting the Id of the first item of the list. How can I make that happen?

EDITED MY CODE FOR CONTEXT

EDIT

Thanks to everyone that responded. Your answers didn't solve the issue but I think I might have made the wrong question. I'll give a little bit of context: I'm trying to show a list of Products in a ViewModel where each has an Add to cart button and an input style number on it's side (By using a for each, as I made a List of Products, as shown in my code), and when I click the add to cart button it gives the info of that specific item to the controller.

I don't know if I was doing it wrong. Is this possible? If so, how?

The issue with my code is that no matter which add to cart button I clicked, it always gives the info of the first item on the list only.

1 Answers

Instead of using:

<input type="hidden" name="ProductId" value="@item.ProductId" />                                                                       

Use:

@Html.HiddenFor(modelItem => item.ProductId)

Following code may help you:

@foreach (var item in Model) {    
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Descripcion)
        </td>
        <td>
            @Html.HiddenFor(modelItem => item.ProductId)
            <input type="number" id="Amount" name="Amount"
                   min="1" max="30" value="1">
            <input type="submit" value="+ Add" class="btn btn-primary" />
        </td>
    </tr>
}    

If you are trying to send all data at once you can also use the following example:

@for( int i = 0; i < Model.Count(); ++i)
{
    <tr>
        <td>
            @Html.DisplayFor(modelItem => Model[i].Descripcion)
        </td>
        <td>
            @Html.HiddenFor(modelItem => Model[i].ProductId)
            <input type="number" id="Amount" name="Amount"
                   min="1" max="30" value="1">
            <input type="submit" value="+ Add" class="btn btn-primary" />
        </td>
    </tr>
}

Where as you controller action method may look like:

[HttpPost]public ViewResult(ModelClass model)
{
...
}
Related