Reputation: 1236
Need some advice on an approach. I have designed a view using a table structure to get the layout I need and populate that table with a foreach loop based on my ViewModel.
I essentially want the user to be able to update some of the fields like noofusers etc and I want to have an addotcart button which will pass those values to the controller.
The problem I have at present is the values do not get passed by the form as they exist outside the form.
If I put in the values in the form I loose any formatting that I get from having a table.
If i repeat the values inside the form but change to hidden for, I get the values from the model passed in not the updated values
I have searched some other posts and have another post on here where it is suggested to not use foreach and use a for loop instead, but that doesn't really change anything in relation to the problem I am experiencing above.
Code is shown below - any suggestions on a general approach to achieve a simple form with a nice layout and still be able to pass values to the controller via a form would be appreciated.
@model PagedList.IPagedList<ShoppingCartCatalogue>
@using Mojito.Domain.ViewModels
@using PagedList.Mvc;
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Mojito Products</h2>
<div class="col-md-9"></div>
<div class="col-md-3">
@using (Html.BeginForm("Index", "MojitoProducts", FormMethod.Get))
{
<p>
@Html.TextBox("SearchString", ViewBag.CurrentFilter as string)
<input type="submit" value="Search" />
</p>
}
</div>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.FirstOrDefault().ImageData)
</th>
<th>
@Html.ActionLink("Category", "Index", new { sortOrder = ViewBag.SortByCategory, currentFilter = ViewBag.CurrentFilter })
</th>
<th>
@Html.ActionLink("Product", "Index", new { sortOrder = ViewBag.SortByProduct, currentFilter = ViewBag.CurrentFilter })
</th>
<th>
@Html.DisplayNameFor(model => model.FirstOrDefault().Description)
</th>
<th>
@Html.DisplayNameFor(model => model.FirstOrDefault().TypeOfSubscription)
</th>
<th>
@Html.ActionLink("Price per user", "Index", new { sortOrder = ViewBag.SortByPrice, currentFilter = ViewBag.CurrentFilter })
</th>
<th>
@Html.DisplayNameFor(model => model.FirstOrDefault().NoOfUsers)
</th>
<th>
@Html.DisplayNameFor(model => model.FirstOrDefault().TotalPrice)
</th>
</tr>
@foreach (ShoppingCartCatalogue t in Model)
{
<tr>
<td>
@if (t.ImageData != null)
{
<div class="pull-left" style="margin-right: 10px">
<img class="img-thumbnail" width="75" height="75"
src="@Url.Action("GetImage", "MojitoProducts",
new { t.MojitoProductId })" />
</div>
}
</td>
<td>
@Html.DisplayFor(modelItem => t.Category, new { Name = "Category", id = "Category" })
</td>
<td>
@Html.DisplayFor(modelItem => t.Name, new { Name = "Name", id = "Name" })
</td>
<td>
@Html.DisplayFor(modelItem => t.Description, new { Name = "Description", id = "Description" })
</td>
<td>
@Html.EnumDropDownListFor(modelItem => t.TypeOfSubscription, new { Name = "TypeOfSubscription", id = "TypeOfSubscription" })
</td>
<td>
@Html.DisplayFor(modelItem => t.Price, new { Name = "Price", id = "Price" })
</td>
<td>
@Html.TextBoxFor(modelItem => t.NoOfUsers, new { Name = "NoOfUsers", id = "NoOfUsers", type = "number", min = "1" })
</td>
<td>
@if (t.TypeOfSubscription.ToString() == "Annual")
{
t.TotalPrice = t.Price * 12;
}
else
{
t.TotalPrice = t.Price;
}
@Html.DisplayFor(modelItem => t.TotalPrice, new { Name = "Total Price", id = "Total Price" })
</td>
<td>
@using (Html.BeginForm("AddToCart", "ShoppingCart", FormMethod.Post))
{
<div class="pull-right form-group">
@if (Request.Url != null)
{
@Html.HiddenFor(modelItem => t.TypeOfSubscription, new { Name = "TypeOfSubscription", id = "TypeOfSubscription" })
@Html.HiddenFor(modelItem => t.NoOfUsers, new { Name = "NoOfUsers", id = "NoOfUsers" })
@Html.HiddenFor(modelItem => t.MojitoProductId, new { Name = "MojitoProductId", id = "MojitoProductId" })
@Html.HiddenFor(modelItem => t.Category, new { Name = "Category", id = "Category" })
@Html.HiddenFor(modelItem => t.Name, new { Name = "Name", id = "Name" })
@Html.HiddenFor(modelItem => t.Description, new { Name = "Description", id = "Description" })
@Html.HiddenFor(modelItem => t.Price, new { Name = "Price", id = "Price" })
if (t.TypeOfSubscription.ToString() == "Annual")
{
t.TotalPrice = t.Price * 12;
}
else
{
t.TotalPrice = t.Price;
}
@Html.HiddenFor(modelItem => t.TotalPrice, new { Name = "Total Price", id = "Total Price" })
@Html.Hidden("returnUrl", Request.Url.PathAndQuery)
<input type="submit" class="btn btn-success" value="Add to cart" />
}
</div>
}
</td>
</tr>
}
</table>
<div class="col-md-12">
Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount
</div>
@Html.PagedListPager(Model, page => Url.Action("Index",
new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))
Upvotes: 0
Views: 758
Reputation:
3 possible solutions:
$.post()
method) to post the values to the controller. The
advantage of this method is the user stays on the form and can
continue to add more elements to the shopping cart. The page would
then include a link to the checkout page that shows all items that
have been addedUpvotes: 0
Reputation: 4873
This is a css issue, not really a mvc issue. Compare the css being applied to the table outside of the form, with the css being applied to the table inside the form. It's probably just a matter of adding a class to the table and your css file.
Upvotes: 2