13

I can't find or figure out how to take a list of items (cupcakes) and display them in razor with a quantity field.

What is happening is I am not able to get the values for each cupcake quantity in the list. Can you do textbox arrays in Razor?

VIEW

<div class="form-group">
    <label>Cupcakes</label>
    @foreach (var cupcake in Model.CupcakeList)
    {
        @Html.TextBox("CupcakeQuantities", cupcake.Id)  @cupcake.Name <br/>
    }
</div>

MODEL

public List<Cupcake> CupcakeList { get; set; }
public List<int> CupcakeQuantities { get; set; }

CONTROLLER

public ActionResult Create()
{
    var model = new PartyBookingModel()
    {
        CupcakeList = db.Cupcakes.ToList(),
        CupcakeQuantities = new List<int>()
    };

    return View(model);
}

CUPCAKE (ENTITY)

public class Cupcake
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal PerDozen { get; set; }
}
2
  • Your question seems to be inconsistent, you're showing CupcakeQuantites in your model, but in controller you're filling CupcakeSelection array. Could you please specify where is your quantity field located? Commented Jun 10, 2014 at 21:10
  • Sorry, typo. Should be the CupcakeQuantities. Question updated. Commented Jun 10, 2014 at 21:15

2 Answers 2

39

You have to use an index, rather than foreach for it to work.

@for (int i = 0; i < Model.CupcakeList.Count; i++)
{
    @Html.TextBoxFor(x=>Model.CupcakeQuantities[i]) @Model.CupcakeList[i].Name <br/>
}

This will create sequentially named+number entries that will be recombined back into the model on post back.

I realise this may seem like "why doesn't foreach work?", but with foreach there is not enough reflected information available to TextBoxFor (as it is just a single object), whereas the array index is extracted by reflection from the Model.CupcakeQuantities[i] expression.

The receiving controller method should take the same as the model passed to the view:

e.g.

[HttpPost]
public ActionResult(PartyBookingModel model)
Sign up to request clarification or add additional context in comments.

7 Comments

Yes, that is what I was trying to figure out. But I don't know how to "capture" the values on post in the controller. Can your answer show that please?
Added example of receiving controller method. When you use the scaffolding wizards for EF models + create, you will usually get a good example to build on.
Just realised I have put the wrong model property in the array... Now fixed to be your quantities :) It would be cleaner if the CupCake model contained a quantity property, rather than have 2 lists. e.g. adding a CupCakeCreate model that derives from CupCake and adds a Qty property is one option.
I am not sure how to implement a CupCakeCreate model into the current model/view/controller. Your thought makes sense but I am a bit of a noob on this :)
Yes my bad. Typed all that from memory. Add basic .Count :)
|
2

Try it this way:

view:

@for (int i = 0; i < Model.Count; i++)
{
    @Html.HiddenFor(x=>Model[i].Id) @Model[i].Name  
    @Html.TextBoxFor(x => Model[i].Quantity) <br/>
}

model:

public class CupcakeViewModel
{
   public int Id {get;set;}
   public string Name {get;set;}
   public int Quantity {get;set;}   
}

controller:

public ActionResult Create()
{
    var model = db.Cupcakes.Select(c => new CupcakeViewModel {
                                                Id = c.Id,
                                                Name = c.Name,
                                                Quantity = 0 
                           })
                           .ToList();

    return View(model);
}

[HttpPost]
public ActionResult Create(CupcakeViewModel[] cakes)
{
     //Save choosen cakes
}

6 Comments

I am getting textboxes with "ProjectTest.Domain.Cupcake" text inside of them.
@Html.TextBoxFor(x=>Model.CupcakeList[i].Id) puts the Id in the value of the textbox, I need it to be empty as the user is entering in how many of each they want. I changed it to @Html.TextBoxFor(x=>Model.CupcakeList[i].Id, null) but it won't let me assign an int (Id) to a string. :(
Which property do you want to allow user to change? If it's Id - why is it should be empty? for geting it empty you should pass object with Value = "" like this: @Html.TextBoxFor(x=>Model.CupcakeList[i].Id, new { Value = "" })
The way I am trying to make the form is 1) Call database, get list of cupcakes 2) display cupcakes with qty field for user to enter how many of each they want 3) Get values and build a order from each qty.
Thanks, actually I copied your code as template )))
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.