Ok so i'm trying to use a viewmodel with a list box such that when i add items to the listbox and then post the form, those items are carried over through the viewmodel to the action.
ViewModel:
public virtual ICollection<Sku> Skus { get; set; } //This is this items sku's
public virtual ICollection<Sku> AllSkus { get; set; } //This is all sku's
My Listbox looks like this:
@Html.ListBoxFor(m=>m.Skus, new MultiSelectList(Model.Skus, "Id", "Name"), new { id = "skuList", style="width: 200px; height: 100px" })
I have a table full of all skus that when i select one, it adds to the list box using jquery. (I'll post all that code below)
My receiving action (skus is null):
[HttpPost]
public ActionResult AddProductOffering(ProductOfferingModel model)
{
return View(model);
}
The items are adding to the listbox just fine, however the model is still null after the post.
Clearly i am just updating the listbox and not the model, i do not know how to tie the two together in this way.
Any help would be much appreciated, thank you!
(Updated) Full .cshtml file:
@using Web.ControlPanel.Helpers
@model Web.ControlPanel.ViewModels.Offering.ProductOfferingModel
@using (Html.BeginForm())
{
<h2>Product Offering</h2>
<br />
@Html.LabelFor(m => m.Name)
@Html.EditorFor(m => m.Name)
<br />
<br />
<label>Offerings Skus</label><br/>
@Html.ListBoxFor(m=>m.Skus, new MultiSelectList(Model.Skus, "Id", "Name"), new { id = "skuList", style="width: 200px; height: 100px" })
<br/><br/>
<button class="button" type="submit" value="Save">Save</button>
<br/><br/><br/>
<h3>All Skus</h3>
<p>
Search: @Html.TextBox("skuFilter")
<input type="submit" value="Search Skus" name="search" />
</p>
<table class="onepx" style="width: 80%">
<tr>
<td colspan="4" style="text-align: right;">
@Html.Pager("List", Model.SkuPager, 3, (string)ViewBag.SkuFilter)
</td>
</tr>
<thead>
<tr style="font-weight: bold;">
<td>Product</td>
<td>Sku</td>
<td>List Price</td>
<td>MSRP</td>
<td>Action</td>
</tr>
</thead>
<tbody>
@if (Model.Skus != null)
{
foreach (var sku in Model.AllSkus)
{
<tr>
<td>
@Html.DisplayFor(m => sku.Product.Name)
</td>
<td>
<label id="skuName@(sku.Id)">@sku.Name</label>
</td>
<td>[email protected](m => sku.ListPrice)
</td>
<td>[email protected](m => sku.Msrp)
</td>
<td>
<a href="#" class="AddSku" id="addSku@(sku.Id)">Add To Offering</a>
</td>
</tr>
}
}
</tbody>
<tfoot>
<tr>
<td colspan="4" style="text-align: right;">
@Html.Pager("List", Model.SkuPager, 3, (string)ViewBag.SkuFilter)
</td>
</tr>
</tfoot>
</table>
}
@section Scripts {
<script>
$(document).ready(function() {
//Array of skus
var skus = new Array();
$('.AddSku').click(function(e) {
e.preventDefault();
var id = e.target.id.replace("addSku", "");
var exists = false;
for (var i = 0; i < skus.length; i++) {
if (skus[i] == id) {
exists = true;
}
}
if (!exists) {
var name = $("#skuName" + id).text();
$('#skuList').append('<option value=' + id + '>' + name + '</option>');
skus.push(id);
}
});
});
</script>
}
MVC can't technically bind to an interface of types (or objects) - ICollection
- change your ICollection<T>
to List<T>
. Then you need to look at how the List is being rendered in your ListBox (select). It should be rendered in array notation, i.e. something like Sku[0] ... Sku[n]
. Your jQuery needs to append to the select in the same array notation. Read Phil Haack's Model Binding to a List article for more info.