I have the following View (see below) - The idea is it will display any existing brand items in a table, but also give the user the ability to add new brand items (and upload an associated brand file). Visually it works the way it should. The user clicks the button to dynamically add a append a new table row with the empty fields.
The issue I'm having, is that the newly added rows in the table aren't being binded to the ViewModel, so when I hit submit, and debug into my Action, there is only one (or however many rows were pre existing) binded to the ViewModel. I'm also unsure how to get this information from the formValues variable as it would be unfeasible to retrive each row as:
BrandItems[1].Identifier, BrandItems[2].Identifier
as I will never know how many exist.
Another problem I'm having with this method is binding the file upload to the model also.
Any help would be greatly appreciated. Any questions or need more information just ask.
Here is my View:
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Main.Master"
Inherits="System.Web.Mvc.ViewPage<MyProject.Web.Models.BrandViewModel>" %>
<%@ Import Namespace="MyProject.Extensions" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<% Html.BeginForm("EditBrandItems", "Brands"); %>
<table class="normal" border="1px" cellpadding="2px" style="border-collapse: collapse; width: 530px;">
<tr>
<th style="text-align: left;">
Delete
</th>
<th style="text-align: left;">
Type
</th>
<th style="text-align: left;">
Identifier
</th>
<th>
File Upload
</th>
</tr>
<% for (int i = 0; i < Model.BrandItems.Count; i++) %>
<% { %>
<% var tb = Model.BrandItems[i]; %>
<tr class="BrandItems-editor">
<td style="text-align: center;">
<%: Html.HiddenFor(m => m.BrandItems[i].BrandItemID) %>
<%: Html.HiddenFor(m => m.BrandItems[i].BrandID) %>
<%: Html.HiddenFor(m => m.BrandItems[i].FileName) %>
<%: Html.HiddenFor(m => m.BrandItems[i].BrandItemType.Name) %>
<%: Html.EditorFor(m => m.BrandItems[i].Deleted) %>
</td>
<td style="text-align: center;">
<%: tb.BrandItemType.Name %>
</td>
<td style="text-align: center;">
<%: Html.EditorFor(m => m.BrandItems[i].Identifier) %>
</td>
<td>
<input name="ASSET_<%: Model.BrandItems[i].BrandItemID %>" type="file" id="ASSET_<%: Model.BrandItems[i].BrandItemID %>" />
</td>
</tr>
<% if (i == 0) { %>
<tr class="BrandItems-editor-template" style="display:none">
<td style="text-align: center;">
<%: Html.EditorFor(m => m.BrandItems[i].Deleted) %>
</td>
<td style="text-align: center;">
<%: Html.EditorFor(m => m.BrandItems[i].BrandItemType.Name) %>
</td>
<td style="text-align: center;">
<%: Html.EditorFor(m => m.BrandItems[i].Identifier) %>
</td>
<td>
<input name="NEWASSET_<%: Model.BrandItems[i].BrandID %>" type="file" id="NEWASSET_<%: Model.BrandItems[i].BrandID %>" />
</td>
</tr>
<% } %>
<% } %>
</table>
<br />
<input type="button" class="add-button" name="add" value="Add" />
<% Html.RenderPartial("UpdateButtons"); %>
<% Html.EndForm(); %>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="Header" runat="server">
<script type="text/javascript">
$(document).ready(function () {
var count = 2;
$('.add-button').click(function () {
count++;
var template = $('.BrandItems-editor-template').clone()
template.find('input[type=text]').val('');
$.each(template.find('input[type=text]'), function () {
var name = $(this).attr('name');
name = name.replace('0', count - 1);
$(this).attr('name', name);
});
$('.normal').append(template);
template.removeClass('BrandItems-editor-template').addClass('BrandItems-editor').show();
})
});
</script>
</asp:Content>
Here is my action method within my controller:
[HttpPost]
[ValidateInput(false)]
public virtual ActionResult EditBrandItems(BrandViewModel model, FormCollection formValues)
{
//DO SOMETHING WITH DATA
return View(model);
}
HEre is the BrandViewModel - (BrandItems is a list within this model)
public class BrandViewModel
{
public BrandViewModel()
{
Brand = new Brand();
BrandItems = new List<Data.BrandItem>();
}
public Data.Brand Brand { get; set; }
public List<Data.Brand> BrandItems { get; set; }
}