Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC5 Add Item to List

Given a Model of :

public class Receipt: BaseEntity
{
    [Required(AllowEmptyStrings = false,ErrorMessage = "Please Select A Store")]
    public Store  Store { get; set; }
    public List<Item> Items { get; set; }
    public Item NewItem { get; private set; }
    [Required(AllowEmptyStrings = false,ErrorMessage = "ReceiptModel.EntryDate is required")]
    public DateTime EntryDate { get; set; }
    public Guid EntryOwner { get; set; }
    public string Name { get; set; }

    public double ReceiptTotal()
    {
        return Items.Sum(item => item.ItemPrice);
    }
    public Receipt()
    {
        Items = new List<Item>();
        EntryOwner = Guid.Empty;
        EntryDate = DateTime.Now;
        Store = new Store();
        NewItem = new Item();
     }       
}

And a Controller :

public class ReceiptController : Controller
{
    //
    // GET: /Receipt/

    public ActionResult Index()
    {
        Receipt receipt = new Receipt();
        return View(receipt);
    }

    [HttpPost]
    public ActionResult AddItem(Receipt receipt)
    {
        receipt.Items.Add(receipt.NewItem);
        if (ModelState.IsValid)
        {
            return View("Index", receipt);
        }
        return View("Index", receipt);
    }

And a View: Updated View - Removed all partial pages and combined into a single page

<form class="form-horizontal" method="POST" action="@Url.Action("AddItem","Receipt")">
<div class="jumbotron">
    <div id="main" class="panel panel-primary">

        <div class="panel-heading"> <h1 class="panel-title">Receipt Builder</h1></div>
        <div class="panel-body">

            <fieldset>
                @Html.LabelFor(model => model.Name)
                @Html.EditorFor(model => model.Name)

                @Html.LabelFor(model => model.Store.Name)
                @Html.EditorFor(model => model.Store.Name)

                @Html.LabelFor(model => model.EntryDate)
                @Html.EditorFor(model => model.EntryDate)
            </fieldset>

        </div>


    </div>
</div>

<table class="table table-bordered table-condensed table-hover table-responsive table-striped">
    <thead>
        <tr>
            <td>
                <label class="control-label">#</label>
            </td>
            <td>
                <label class="control-label">Item</label>
            </td>
            <td>
                <label class="control-label">Unit</label>
            </td>
            <td>
                <label class="control-label">Quantity</label>
            </td>
            <td>
                <label class="control-label">UnitPrice</label>
            </td>
            <td>
                <label class="control-label">Category</label>
            </td>
            <td>
                <label class="control-label">Total</label>
            </td>
        </tr>
        <tr>

                <td>
                    <button class="btn-sm btn-danger" style="border-radius: 50%; background-color: red;" name="Submit" id="Submit" type="submit">+</button>
                </td>

                <td>
                    @Html.EditorFor(model => model.NewItem.Name)
                </td>

                <td>
                    @Html.EditorFor(model => model.NewItem.UnitType)
                </td>

                <td>
                    @Html.EditorFor(model => model.NewItem.Quantity)
                </td>

                <td>
                    @Html.EditorFor(model => model.NewItem.UnitPrice)
                </td>

                <td>
                    @Html.EditorFor(model => model.NewItem.Category.Name)<br/>
                    @Html.EditorFor(model => model.NewItem.Category.IsTaxable)
                </td>

                <td>
                    @Html.EditorFor(model => model.NewItem.ItemPrice)
                </td>


        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Items)
        {
            <tr>
                <td>
                    @Model.Items.ToList().IndexOf(item) + 1
                </td>
                <td>
                    @Html.LabelFor(titem => item.Name)
                </td>
                <td>
                    @Html.LabelFor(titem => item.UnitType)
                </td>
                <td>
                    @Html.LabelFor(titem => item.Quantity)
                </td>
                <td>
                    @Html.LabelFor(titem => item.UnitPrice)
                </td>
                <td>
                    @Html.LabelFor(titem => item.Category.Name)
                </td>
                <td>
                    @Html.LabelFor(titem => item.ItemPrice)
                </td>
            </tr>
        }
    </tbody>

    <tfoot></tfoot>
</table>

like image 663
Wjdavis5 Avatar asked Mar 21 '23 15:03

Wjdavis5


1 Answers

I was finally able to resolve this thanks to This Link

It was indeed a binding issue as was suggested. It seems that with complex collections such as Lists we cannot actually utilize the benefits of IEnumerable like I had hoped. This is due to how the data is actually passed in the post having names that are ambiguous. Here is the final code that is working (only have to update the view)

 @for (int i = 0; i < Model.Items.Count(); i++)
        {
            <tr>
                <td>
                @(i+1)
                </td>
                <td>
                    @Html.TextBoxFor(m => m.Items[i].Name)
                </td>
                <td>
                    @Html.TextBoxFor(m => m.Items[i].UnitType)
                </td>
                <td>
                    @Html.TextBoxFor(m => m.Items[i].Quantity)
                </td>
                <td>
                    @Html.TextBoxFor(m => m.Items[i].UnitPrice)
                </td>
                <td>
                    @Html.TextBoxFor(m => m.Items[i].Category.Name)
                </td>
                <td>
                    @Model.Items[i].ItemPrice
                </td>
            </tr>
        }

The resulting HTML names each element with its index ie Item[N].Name Now the post data can be bound correctly.

like image 139
Wjdavis5 Avatar answered Apr 01 '23 21:04

Wjdavis5