Reputation: 578
I am doing a sort with the orderby and orderbydescending list functions but only the fields that are readonly sort correctly. Can you please help me out solve this. Thanks.
Controller code:
public ActionResult ProductList()
{
var productList = new ProductListViewModel();
productList.ProductItems = productRepository.GetProductsWithDeleteOption().ToList();
productList.CategoryItems = categoryRepository.GetCategories().ToList();
var sortList = GetSortList();
productList.SortByList = sortList;
productList.SelectedSortByValue = "ProductID";
return View(productList);
}
[HttpPost]
public ActionResult ProductList(ProductListViewModel productViewModel, FormCollection formCollection, string submit)
{
if (ModelState.IsValid)
{
var sortList = GetSortList();
productViewModel.SortByList = sortList;
productViewModel.CategoryItems = categoryRepository.GetCategories().ToList();
productViewModel.SortByList = sortList;
// Check for submit action
if (submit == "Change Sort")
{
if (formCollection["SortDirection"] == "Desc")
{
switch (productViewModel.SelectedSortByValue)
{
case "ProductID": productViewModel.ProductItems = productViewModel.ProductItems.OrderByDescending(m => m.ProductID).ToList(); break;
case "Code": productViewModel.ProductItems = productViewModel.ProductItems.OrderByDescending(m => m.Code).ToList(); break;
case "Name": productViewModel.ProductItems = productViewModel.ProductItems.OrderByDescending(m => m.Name).ToList(); break;
case "Price": productViewModel.ProductItems = productViewModel.ProductItems.OrderByDescending(m => m.Price).ToList(); break;
default: productViewModel.ProductItems = productViewModel.ProductItems.OrderByDescending(m => m.ProductID).ToList(); break;
}
}
else
{
switch (productViewModel.SelectedSortByValue)
{
case "ProductID": productViewModel.ProductItems = productViewModel.ProductItems.OrderBy(m => m.ProductID).ToList(); break;
case "Code": productViewModel.ProductItems = productViewModel.ProductItems.OrderBy(m => m.Code).ToList(); break;
case "Name": productViewModel.ProductItems = productViewModel.ProductItems.OrderBy(m => m.Name).ToList(); break;
case "Price": productViewModel.ProductItems = productViewModel.ProductItems.OrderBy(m => m.Price).ToList(); break;
default: productViewModel.ProductItems = productViewModel.ProductItems.OrderBy(m => m.ProductID).ToList(); break;
}
}
}
else if (submit == "Delete all selected")
{
}
else if (submit == "Update All")
{
}
else if (submit == "Restrict Display")
{
}
}
return View(productViewModel);
}
View:
@for (var i = 0; i < Model.ProductItems.Count; i++)
{
<tr>
<td>
@Html.HiddenFor(m => m.ProductItems[i].ProductID)
@Html.ActionLink(Model.ProductItems[i].ProductID.ToString(), "ProductEdit", new { id = Model.ProductItems[i].ProductID })
</td>
<td>
@Html.HiddenFor(m => m.ProductItems[i].Code)
@Html.DisplayFor(m => m.ProductItems[i].Code)
</td>
<td>
@Html.HiddenFor(m => m.ProductItems[i].Name)
@Html.DisplayFor(m => m.ProductItems[i].Name)
</td>
<td>
@Html.EditorFor(m => m.ProductItems[i].Price)
</td>
<td>
@Html.CheckBoxFor(m => m.ProductItems[i].On_Sale, new { id = "On_Sale_" + Model.ProductItems[i].ProductID })
</td>
<td>
@Html.EditorFor(m => m.ProductItems[i].DiscountedPrice)
</td>
<td>
@Html.EditorFor(m => m.ProductItems[i].Weight)
</td>
<td>
@Html.CheckBoxFor(m => m.ProductItems[i].IsForDelete, new { id = Model.ProductItems[i].ProductID })
</td>
<td>
@Html.ActionLink("Edit", "ProductEdit", new { id = Model.ProductItems[i].ProductID }) |
@Html.ActionLink("Details", "Details", new { id = Model.ProductItems[i].ProductID }) |
@Html.ActionLink("Delete", "Delete", new { id = Model.ProductItems[i].ProductID })
</td>
</tr>
}
Upvotes: 0
Views: 818
Reputation: 2356
I ran into a similar issue and was able to get the checkbox value back by using a checkbox, hiddenfor and little JQuery like so:
@Html.CheckBox("isPreferred", Model.IsPreferred)
@Html.HiddenFor(m => m.IsPreferred)
<script>
$("#isPreferred").change(function () {
$("#IsPreferred").val($("#isPreferred").val());
})
</script>
Upvotes: 0
Reputation: 4054
This may be an instance where you can't rely on Html.CheckBoxFor<T>()
but instead should use Html.CheckBox()
to manually bind the Ids
and values you're looking for.
It's not the nicest, but it's seemed to work for me before. Here's a psuedo-code example of the View
as I'm thinking about it in my head:
@for (var i = 0; i < Model.ProductItems.Count; i++)
{
<tr>
<td>
@Html.HiddenFor(m => m.ProductItems[i].ProductID)
@Html.ActionLink(Model.ProductItems[i].ProductID.ToString(), "ProductEdit", new { id = Model.ProductItems[i].ProductID })
</td>
<td>
@Html.HiddenFor(m => m.ProductItems[i].Code)
@Html.DisplayFor(m => m.ProductItems[i].Code)
</td>
<td>
@Html.HiddenFor(m => m.ProductItems[i].Name)
@Html.DisplayFor(m => m.ProductItems[i].Name)
</td>
<td>
@Html.EditorFor(m => m.ProductItems[i].Price)
</td>
<td> **CHANGE HERE**
@Html.CheckBox(string.format("On_Sale_{0}", Model.ProductItems[i].ProductID), Model.ProductItems[i].IsOnSale)
@Html.CheckBoxFor(m => m.ProductItems[i].On_Sale, new { id = "On_Sale_" + Model.ProductItems[i].ProductID })
</td>
<td>
@Html.EditorFor(m => m.ProductItems[i].DiscountedPrice)
</td>
<td>
@Html.EditorFor(m => m.ProductItems[i].Weight)
</td>
<td>
@Html.CheckBoxFor(m => m.ProductItems[i].IsForDelete, new { id = Model.ProductItems[i].ProductID })
</td>
<td>
@Html.ActionLink("Edit", "ProductEdit", new { id = Model.ProductItems[i].ProductID }) |
@Html.ActionLink("Details", "Details", new { id = Model.ProductItems[i].ProductID }) |
@Html.ActionLink("Delete", "Delete", new { id = Model.ProductItems[i].ProductID })
</td>
</tr>
}
Upvotes: 1