No model binding with editor template - asp.net-mvc

I have following view:
#model StockItemDetailModel
#using (Html.BeginForm("EditDetails", "StockItem"))
{
<div class="ItemDetails">
<table class="datagrid">
<tr>
<th colspan="3">#Model.StockItemPropertiesCaption</th>
</tr>
<tr>
<td class="label">#Model.StoreLabel</td>
<td class="value">#Html.DisplayFor(item => item.Store)</td>
<td></td>
</tr>
<tr>
<td class="label">#Model.BuildingLabel</td>
<td class="value">#Html.DevExpress().TextBoxFor(model => model.Building).GetHtml()</td>
<td class="validationError">#Html.ValidationMessageFor(model => model.Building)</td>
</tr>
...
<tr>
<td colspan="3">#Html.EditorFor(model => model.AmountModel, "Amounts")</td>
> </tr>
<tr>
<td colspan="3" class="validationError">#Html.ValidationMessageFor(model => model.AmountModel)</td>
</tr>
<tr />
</table>
</div>
<br />
<input type="submit" class="button" value="#Model.SaveButtonLabel" />
}
The partial View "Amounts" is as follows:
#model AmountModel
<table>
<tr>
<td class="label">#Model.AmountLabel</td>
<td class="value">
#Html.DevExpress().SpinEditFor(model => model.DenormalizedNetAmount,
settings =>
{
settings.Name = "DenormalizedNetAmount";
settings.Width = 153;
settings.Properties.DisplayFormatString = #"0.0,0";
settings.Number = 0;
}).GetHtml()
</td>
<td class="value">
#Html.DevExpress().ComboBoxFor(model => model.NetAmountUnit,
settings =>
{
settings.Name = "NetAmountUnit";
settings.Width = 60;
}).BindList(args => this.Model.AllUnits, args => this.Model.AllUnits).GetHtml()
</td>
</tr>
...
</table>
This is the AmountModel:
public class AmountModel
{
public decimal DenormalizedNetAmount { get; set; }
public string NetAmountUnit { get; set; }
...
public string AmountLabel
{
get { return i18n.StockItemDetailModel_AmountLabel; }
}
...
}
But the values of the input fields are not in the model in the Controller created by the model binder.
Why does the model binder not recognize the values in the editor template?
When I passed the FormCollection the values where correctly passed under the names "AmountModel.~"
public ActionResult EditDetails(FormCollection collection)
{
var netamount = collection["AmountModel.DenormalizedNetAmount"]; //correct value!
...
}

Do NOT specify the Name property when using the strong-typed (***For) helpers.
See the MVC Data Editors - Model Binding and Editing learning resource on the DevExpress forum.

Related

'Object reference not set to an instance of an object' Error when trying to move contents from view page to another

I have a button in my Index.html page which shows another view page: Reports.cshtml, there is a table inside the page, now I want to remove this button and let the table showing on my Index.html page directly, but when I paste the table to the code it shows an error:
Error
Part of my view code are showed below:
<table id="hardware-data-table" class="table table-striped table-hover">
<thead bgcolor="silver">
<tr>
<th hidden="hidden">
#Html.LabelFor(model => model.Report_HardwareListByExpiration.FirstOrDefault().InvHardwareID)
</th>
<th>
#Html.LabelFor(model => model.Report_HardwareListByExpiration.FirstOrDefault().Equipment)
</th>
<th>
#Html.LabelFor(model => model.Report_HardwareListByExpiration.FirstOrDefault().HardwareModel)
</th>
<th>
#Html.LabelFor(model => model.Report_HardwareListByExpiration.FirstOrDefault().WL_EndDateFormatted)
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.Report_HardwareListByExpiration)
{
if (item.WL_EndDate < DateTime.Now && item.WL_EndDate > DateTime.Now.AddYears(-99))
{
<tr>
<td hidden="hidden">
#item.InvHardwareID
</td>
<td>
#item.Equipment
</td>
<td>
#item.HardwareModel
</td>
<td style="background-color: #ff726f">#item.WL_EndDateFormatted</td>
</tr>
}
if (item.WL_EndDate > DateTime.Now && item.WL_EndDate < DateTime.Now.AddYears(99))
{
<tr>
<td hidden="hidden">
#item.InvHardwareID
</td>
<td>
#item.Equipment
</td>
<td>
#item.HardwareModel
</td>
<td style="background-color: orange">
#item.WL_EndDateFormatted
</td>
</tr>
}
}
</tbody>
</table>
My Report controller code are showed below:
public class ReportsController : Controller
{
// GET: Report
public ActionResult Reports()
{
if (Session["UserID"] == null || !(bool)Session["IsLoggedIn"])
{
return RedirectToAction("Login", "Account");
}
ViewModel myViewModel = new ViewModel
{
User = GetSessionInfoFromSessions(),
Params = new ParametersModel
{
Start_Date = new DateTime(2015, 12, 31),
End_Date = DateTime.Now.AddDays(60)
}
};
myViewModel.Report_HardwareListByExpiration = InvHardwareModel.Report_HardwareListByExpiration(myViewModel);
return View(myViewModel);
}
And my hardware Model:
public static List<InvHardwareModel> Report_HardwareListByExpiration(ViewModel myViewModel)
{
try
{
var myAssManEnt = new AssetManagementEntities();
var myUspList = myAssManEnt.usp_Report_InvHardware_ByExpirationDates
(
agencyID : myViewModel.User.AgencyID,
deptID : myViewModel.User.DeptID,
roleID : myViewModel.User.RoleID,
startDate : myViewModel.Params.Start_Date,
endDate : myViewModel.Params.End_Date
).ToList();
var myReturnList = new List<InvHardwareModel>();
foreach(usp_Report_InvHardware_ByExpirationDates_Result myItem in myUspList)
{
myReturnList.Add(Models.InvHardwareModel.ToModel(myItem));
}
return myReturnList;
}
catch(Exception e)
{
throw ErrorHandler.MyException(e, "InvHardwareModel.Report_HardwareListByExpiration");
}
}
The code works perfect when its in the other view page, but shows exception when I move it to my home page, any ideas? Thank you so much!

Controller can't receive model data [duplicate]

This question already has answers here:
Post an HTML Table to ADO.NET DataTable
(2 answers)
Closed 6 years ago.
Hi I want to grab all user modify data.
My question is why controller can't receive the model data from View in my project.
Please explain why this error was caused and how to solve it.
Models:
public class ShoppingCart
{
public List<ShoppingCartItemModel> items = new List<ShoppingCartItemModel>();
public IEnumerable<ShoppingCartItemModel> Items
{
get { return items; }
}
}
public class ShoppingCartItemModel
{
public Product Product
{
get;
set;
}
public int Quantity { get; set; }
}
Controller
[HttpPost]
public RedirectToRouteResult EditFromCart(ShoppingCart MyModel)
{
ShoppingCart cart = GetCart();
foreach (var CartItem in cart.items)
{
foreach (var ReceiveModelItem in MyModel.items)
{
if (CartItem.Product.ProductID == ReceiveModelItem.Product.ProductID)
{
CartItem.Quantity = ReceiveModelItem.Quantity;
}
}
}
return RedirectToAction("Index", "ShoppingCart");
}
View
#model ShoppingCart
#{
ViewBag.Title = "購物車內容";
}
<h2>Index</h2>
<table class="table">
<thead>
<tr>
<th>
Quantity
</th>
<th>
Item
</th>
<th class="text-right">
Price
</th>
<th class="text-right">
Subtotal
</th>
</tr>
</thead>
<tbody>
#using (Html.BeginForm("EditFromCart", "ShoppingCart", FormMethod.Post))
{
foreach (var item in Model.items)
{
<tr>
<td class="text-center">
#item.Product.ProductName
</td>
<td class="text-center">
#item.Product.Price.ToString("c")
</td>
<td class="text-center">
#( (item.Quantity * item.Product.Price).ToString("c"))
</td>
<td class="text-left">
#Html.EditorFor(model => item.Quantity, null, "UserInputQuantity")
#Html.Hidden("ProductId", item.Product.ProductID)
</td>
</tr>
}
<tr>
<td colspan="3">
<input class="btn btn-warning" type="submit" value="Edit">
</td>
</tr>
}
</tbody>
</table>
You must explicitly create a hidden input for each property in your complex object that you want to be bound. IEnumerables and binding don't play very nicely directly out of the box - it looks like MVC has better base support for IList<> and arrays, but you'll still have to enumerate the collection and create hidden inputs for each item. Have a look at this link. So, ideally your view should be:
#model ShoppingCart
#{
ViewBag.Title = "購物車內容";
}
<h2>Index</h2>
<table class="table">
<thead>
<tr>
<th>
Quantity
</th>
<th>
Item
</th>
<th class="text-right">
Price
</th>
<th class="text-right">
Subtotal
</th>
</tr>
</thead>
<tbody>
#using (Html.BeginForm("EditFromCart", "ShoppingCart", FormMethod.Post))
{
for (int i = 0; i < Model.items.Count(); ++i)
{
<tr>
<td class="text-center">
#Model.items[i].Product.ProductName
</td>
<td class="text-center">
#Model.items[i].Product.Price.ToString("c")
</td>
<td class="text-center">
#( (Model.items[i].Quantity * Model.items[i].Product.Price).ToString("c"))
</td>
<td class="text-left">
#Html.EditorFor(model => Model.items[i].Quantity)
#Html.HiddenFor(model => Model.items[i].Product.ProductID)
#Html.HiddenFor(model => Model.items[i].Product.ProductName)
#Html.HiddenFor(model => Model.items[i].Product.Price)
</td>
</tr>
}
<tr>
<td colspan="3">
<input class="btn btn-warning" type="submit" value="Edit">
</td>
</tr>
}
</tbody>
</table>
Names are not correctly set for your text and hidden inputs:
#Html.EditorFor(model => item.Quantity, null, "UserInputQuantity")
#Html.Hidden("ProductId", item.Product.ProductID)
If you inspect elements you can see names are UserInputQuantity and ProductId, but they should be
items[i].Quantity and items[i].Product.ProductID respectively.
You can take a look at this link:
MVC Model binding of complex objects

MVC DisplayFor template table with duplicated headers

Using a EditorFor template and trying to create a table, how can I get only one header row instead of one for each item of the collection?
Being the viewmodel
public class CashbackOfferViewModel
{
public List<SingleCashbackOfferViewModel> Offers { get; set; }
}
In the view I have
#Html.DisplayFor(m => m.Offers)
And the display template is
#using LMS.MVC.Infrastructure
#model LMS.MVC.Areas.Finance.Models.SingleCashbackOfferViewModel
<table class="dataGrid">
<thead>
<tr class="headerRow">
<th>#Html.LabelFor(m => m.CampaignName)</th>
<th>#Html.LabelFor(m => m.PersonId)</th>
<th>#Html.LabelFor(m => m.FullName)</ths>
</tr>
</thead>
<tbody>
<tr>
<td>#Html.DisplayFor(m => m.CampaignName)</td>
<td>#Html.DisplayFor(m => m.PersonId)</td>
<td>#Html.DisplayFor(m => m.FullName)</td>
</tr>
</tbody>
</table>
One solution can be:
Create display template for your whole model
#using LMS.MVC.Infrastructure
#model LMS.MVC.Areas.Finance.Models.CashbackOfferViewModel
<table class="dataGrid">
<thead>
<tr class="headerRow">
<th>CampaignName</th>
<th>PersonId</th>
<th>FullName</ths>
</tr>
</thead>
<tbody>
#for(int i = 0; i < Model.Offers.Count; ++i)
{
<tr>
<td>#Html.DisplayFor(m => m.Offers[i].CampaignName)</td>
<td>#Html.DisplayFor(m => m.Offers[i].PersonId)</td>
<td>#Html.DisplayFor(m => m.Offers[i].FullName)</td>
</tr>
}
</tbody>
</table>
Also i think in your code, your model must be List of SingleCashbackOfferViewModel and you can easily iterate over the list and create table

All model and Formcollection values are null, blank or don't exist in Firefox or Chrome

During debugging, my MVC model and Formcollection are blank with no values in FireFox (15) or Chrome (latest version).
During debugging using IE (9), I can see these values just fine.
Do you know what the solution is for this? This is very serious for public facing web sites not being able to do any programming angainst these browsers.
Here is my View...
#model PDFConverterModel.ViewModels.ViewModelTemplate_Guarantors
#{
ViewBag.Title = "BHG :: PDF Generator";
}
<h2>#ViewBag.Message</h2>
<div>
<table style="width: 1000px">
<tr>
<td colspan="5">
<img alt="BHG Logo" src="~/Images/logo.gif" />
</td>
</tr>
#using (Html.BeginForm("ProcessForm", "Home", FormMethod.Post))
{
<tr>
<td>
#(Html.Kendo().IntegerTextBox()
.Name("LoanID")
.Placeholder("Enter Loan ID")
)
</tr>
<tr>
<td>#Html.LabelFor(model => model.LoanType)
#Html.DisplayFor(model => model.LoanType)
</td>
<td>
<label for="ddlDept">Department:</label>
#(Html.Kendo().DropDownList()
.Name("ddlDept")
.DataTextField("DepartmentName")
.DataValueField("DepartmentID")
.Events(e => e.Change("Refresh"))
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetDepartments", "Home");
});
})
)
</td>
</tr>
if (Model.ShowGeneratePDFBtn == true)
{
if (Model.ErrorT == string.Empty)
{
<tr>
<td colspan="5">
<u><b>#Html.Label("Templates:")</b></u>
</td>
</tr>
<tr>
#for (int i = 0; i < Model.Templates.Count; i++)
{
<td>
#Html.CheckBoxFor(model => Model.Templates[i].IsChecked)
#Html.DisplayFor(model => Model.Templates[i].TemplateId)
</td>
}
</tr>
}
else
{
<tr>
<td>
<b>#Html.DisplayFor(model => Model.ErrorT)</b>
</td>
</tr>
}
if (Model.ErrorG == string.Empty)
{
<tr>
<td colspan="5">
<u><b>#Html.Label("Guarantors:")</b></u>
</td>
</tr>
<tr>
#for (int i = 0; i < Model.Guarantors.Count; i++)
{
<td>
#Html.CheckBoxFor(model => Model.Guarantors[i].isChecked)
#Html.DisplayFor(model => Model.Guarantors[i].GuarantorFirstName) #Html.DisplayFor(model => Model.Guarantors[i].GuarantorLastName)
</td>
}
</tr>
}
else
{
<tr>
<td>
<b>#Html.DisplayFor(model => Model.ErrorG)</b>
</td>
</tr>
}
}
<tr>
<td colspan="3">
<input type="submit" name="submitbutton" id="btnRefresh" value='Refresh' />
</td>
#if (Model.ShowGeneratePDFBtn == true)
{
<td>
<input type="submit" name="submitbutton" id="btnGeneratePDF" value='Generate PDF' />
</td>
}
</tr>
<tr>
<td colspan="5">
#Model.Error
</td>
</tr>
}
</table>
</div>
<script type="text/javascript">
$('btnRefresh').on('click', '#btnRefresh', function () {
Refresh();
});
function Refresh() {
var LoanID = $("#LoanID").val();
if (LoanID != "") {
document.forms[0].submit();
}
else {
alert("Please enter a LoanId");
}
}
</script>
I know this is a very old question, but answering this might help people like who are struggling with this issue.
I had a similar issue. The problem lies here:
<table style="width: 1000px">
<tr>
<td colspan="5">
<img alt="BHG Logo" src="~/Images/logo.gif" />
</td>
</tr>
#using (Html.BeginForm("ProcessForm", "Home", FormMethod.Post))
{
<tr>
<td>
#(Html.Kendo().IntegerTextBox()
.Name("LoanID")
.Placeholder("Enter Loan ID")
)
</td>
</tr>
}
</table>
After begin form there are <tr> tags directly! Browsers like chrome and mozilla get confused in such cases. The <table> tag should be inside the form. If we look at your code, which was exactly what I had done, <table> tag was before #using Html.BeginForm.
Internet Explorer somehow understands this, but the other browsers don't.
When I did an inspect element I found that there was a form tag within each <tr> tag and it always returned FormCollection as null. Simply defining <table> within form solved my problem.
So here's how it should be:
<table style="width: 1000px">
<tr>
<td colspan="5">
<img alt="BHG Logo" src="~/Images/logo.gif" />
</td>
</tr>
<tr><td>
#using (Html.BeginForm("ProcessForm", "Home", FormMethod.Post))
{
<table>
<tr>
<td>
#(Html.Kendo().IntegerTextBox()
.Name("LoanID")
.Placeholder("Enter Loan ID")
)
</td>
</tr>
</table>
}
</td></tr>
</table>
I just found out what the issue is by experimneting.
The Telerik MVC widgets don't emit any FormCollection data!!!!
Only EditorFor and TextBoxFor emit these values, plus the input buttons.
What good are these widgets if I can't use the FormCollection values from them???? Especially the DropDownList where I can retrireve data and need the selected value to pass onto other methods.
(This would be better suited as comment, but I can't comment yet)
For future reference, here's a spec (W3C might have something different) for what gets submitted when a form is submitted:
http://www.whatwg.org/specs/web-apps/current-work/multipage/forms.html#category-submit
You can look at whatever HTML was generated to make sure it gets submitted. You could also use something like Fiddler to look at the Http request

Model Binding not working with mvc1

We have very large object called FoodFormViewModel. We go to add page like
FoodFormViewModel foodFormViewModel = new FoodFormViewModel();
return View("Edit", foodFormViewModel);
But when we come to post method like
[AcceptVerbs(HttpVerbs.Post)]
[ValidateInput(false)]
public ActionResult Edit(FoodFormViewModel objViewModel)
{
SaveProcess(objViewModel);
return View(objViewModel);
}
Our objViewModel properties are all blank. Our FoodFormViewModel definition is
#region Properties
public MealPlannerDataManager MPManager { get; set; }
public Food Food { get; set; }
public SelectList FoodGroupLevel1 { get; set; }
public SelectList FoodGroupLevel2 { get; set; }
public SelectList FoodGroupLevel3 { get; set; }
public SelectList FoodType { get; set; }
public SelectList Company { get; set; }
public SelectList Brand { get; set; }
public SelectList NutritionSource { get; set; }
public SelectList DataSource { get; set; }
public SelectList PlannerSource { get; set; }
public SelectList PublishMonth { get; set; }
public SelectList PublishDay { get; set; }
public SelectList PublishYear { get; set; }
public SelectList TagTypes { get; set; }
public List<CheckBoxInfo> MealTime { get; set; }
public List<CheckBoxInfo> Condition { get; set; }
public List<CheckBoxInfo> Allergens { get; set; }
public List<CheckBoxInfo> Occasions { get; set; }
public List<CheckBoxInfo> Others { get; set; }
public List<CheckBoxInfo> SpecialDiet { get; set; }
public List<CheckBoxInfo> Course { get; set; }
public List<CheckBoxInfo> PrepMethod { get; set; }
public List<CheckBoxInfo> Season { get; set; }
public List<CheckBoxInfo> SkillLevel { get; set; }
public List<CheckBoxInfo> Cuisine { get; set; }
public List<CheckBoxInfo> MealPlan { get; set; }
public List<CheckBoxInfo> Products { get; set; }
public List<CheckBoxInfo> AgeGroup { get; set; }
public FoodNutritionInfo NutrInfo { get; set; }
public FoodNutritionInfo AltNutrInfo { get; set; }
Tag dummyTag = new Tag();
TagType dummyTagType = new TagType();
#endregion Properties
WE couldn't figure out the issue. Any help is highly appreciated.
We are using MVC1 with VS 2008
My view contains 3-4 partial views, i am posting one of the partial view here
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MealPlannerAdmin.Models.ViewModel.FoodFormViewModel>" %>
<%# Import Namespace="MealPlannerAdmin.Models.Objects.HTMLHelpers" %>
<%# Import Namespace="MealPlanner.BusinessObjects.Model" %>
<div id="ValidationSummary" style="position: absolute; margin: 110px 0px 0px 620px;
width: 350px; height: 359px; overflow: auto; border: 0px">
<%=Html.ValidationSummary("Please review all tabs for following errors") %>
</div>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td colspan="2">
<div id="foobar" style="color: Red;">
<%=ViewData["CloningMessage"]%></div>
</td>
</tr>
<tr>
<td colspan="2" class="comHead">
<strong>Food Basic Information</strong>
</td>
</tr>
<tr>
<td colspan="2">
<div id="divCloningMessage" class="errMsg">
</div>
</td>
</tr>
<tr>
<td colspan="2">
<div id="divBtnCloneThisFood" style="display: none;">
<input type="button" value="Clone this Food" id="btnCloneThisFood" name="btnCloneThisFood" />
</div>
</td>
</tr>
<tr>
<td width="200" valign="top">
<span id="spanOriginalCreatorLabel"></span>
</td>
<td>
<span id="spanOriginalCreator"></span>
</td>
</tr>
<tr>
<td width="200" valign="top">
<span id="spanClonedByLabel"></span>
</td>
<td>
<span id="spanClonedBy"></span>
</td>
</tr>
<tr>
<td width="200" valign="top">
<label for="lblFoodID">
Food ID:
</label>
</td>
<td>
<span id="spanFoodID" name="spanFoodID">
<%=Model.Food.FoodID%></span>
</td>
</tr>
<tr>
<td valign="top">
<label for="ddlFoodGroupLevel1">
Food Group Level 1: *</label>
</td>
<td>
<%=Html.DropDownList("ddlFoodGroupLevel1", Model.FoodGroupLevel1, new { #class = "dropdown"})%> <%=Html.ValidationMessage("FoodGroupLevel1", "*")%>
</td>
</tr>
<tr>
<td valign="top">
<label for="ddlFoodGroupLevel2">
Food Group Level 2 :
</label>
</td>
<td>
<%=Html.DropDownList("ddlFoodGroupLevel2", Model.FoodGroupLevel2, new { #class = "dropdown" })%> <%=Html.ValidationMessage("FoodGroupLevel2", "*")%>
</td>
</tr>
<tr>
<td valign="top">
<label for="ddlFoodGroupLevel3">
Food Group Level 3:
</label>
</td>
<td>
<%=Html.DropDownList("ddlFoodGroupLevel3", Model.FoodGroupLevel3, new { #class = "dropdown" })%>
</td>
</tr>
<tr>
<td valign="top">
<label for="Food.FoodName">
Food Name: *</label>
</td>
<td>
<%=Html.TextBox("FoodName", Model.Food.FoodName, new { #maxlength = "250" })%> <%=Html.ValidationMessage("FoodName", "*")%>
</td>
</tr>
<tr>
<td valign="top">
<label for="FoodDisplayName">
Food Display Name: *</label>
</td>
<td>
<%=Html.TextBox("FoodDisplayName", Model.Food.FoodDisplayName, new { #maxlength = "250" })%> <%=Html.ValidationMessage("FoodDisplayName", "*")%>
</td>
</tr>
<tr>
<td valign="top">
<label for="ddlFoodType">
Food Type: *</label>
</td>
<td>
<%=Html.DropDownList("ddlFoodType", Model.FoodType, new { #class = "dropdown" })%> <%=Html.ValidationMessage("FoodType", "*")%>
</td>
</tr>
<tr id="rowCompany">
<td valign="top">
<label for="ddlCompany">
<span id="spanCompany" name="spanCompany"></span>
</label>
</td>
<td>
<%=Html.DropDownList("ddlCompany", Model.Company, new { #class = "dropdown" })%> <%=Html.ValidationMessage("Company", "*")%>
</td>
</tr>
<tr id="rowAddCompany">
<td>
</td>
<td>
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td colspan="2" valign="top" class="subHead">
<label for="txtAddCompany">
<span id="spanAddCompany" name="spanAddCompany"></span>
</label>
</td>
</tr>
<tr>
<td>
<%=Html.TextBox("txtAddCompany", string.Empty, new { #id = "txtAddCompany", #maxlength = 100, #boundButton = "btnNewCompany", #catId = Convert.ToInt16(EntityConstants.TagType.Company), #catName = EntityConstants.TagType.Company, #updateEle = "divAgeGroup", #uiUpdateType = "drop-down-list" })%>
<div id="divAddCompanyError" boundbutton="btnNewCompany" class="errHidden">
</div>
<div id="<%=EntityConstants.TagType.Company %>Message" style="display: none; color: Red;">
</div>
</td>
<td>
</td>
</tr>
<tr>
<td>
<%=Html.TextArea("txtAddCompanyDesc", string.Empty, 5, 42, new { #id = "txtAddCompanyDesc", #class = "text-area-classic w374px", #boundButton = "btnNewCompany" })%>
</td>
<td valign="bottom">
<input type="button" value="Add" id="btnNewCompany" />
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td valign="top">
<label for="cblMealTime">
Meal Time:</label>
</td>
<td>
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
<%=Html.CheckBoxGrid("cblMealTime", Model.MealTime, 4) %>
</td>
<td>
<%=Html.ValidationMessage("Meal", "*")%>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td valign="top">
<label for="ddlNutritionSource">
Nutrition Source: *</label>
</td>
<td>
<%=Html.DropDownList("ddlNutritionSource", Model.NutritionSource, new { #class = "dropdown" })%> <%=Html.ValidationMessage("NutritionSource", "*")%>
</td>
</tr>
<tr>
<td valign="top">
<label for="ddlDataSource">
Data Source: *</label>
</td>
<td>
<%=Html.DropDownList("ddlDataSource", Model.DataSource, new { #class = "dropdown" })%> <%=Html.ValidationMessage("DataSource", "*")%>
</td>
</tr>
<tr>
<td valign="top">
<label for="Display">
Display: *</label>
</td>
<td>
<%=Html.RadioButton("Display", true, Model.Food.Display, new { #id = "DisplayTrue" })%><label>Yes</label>
<%=Html.RadioButton("Display", false, !(Model.Food.Display), new { #id = "DisplayFalse" }) %><label>No</label>
</td>
</tr>
<tr>
<td valign="top">
<label for="Issue">
Issue: *</label>
</td>
<td>
<%=Html.RadioButton("Issue", true, Model.Food.Issue, new {#id="IssueTrue", #onclick= "disableIssueText()"})%><label>Yes</label>
<%=Html.RadioButton("Issue", false, !(Model.Food.Issue), new {#id="IssueFalse", #onclick = "disableIssueText()" })%><label>No</label>
</td>
</tr>
<tr>
<td valign="top">
<label for="IssueDescription">
Describe Issue:
</label>
</td>
<td>
<%=Html.TextArea("IssueDescription", Model.Food.IssueDescription, 4, 75, new { #maxlength = "50", #class = "w500px" })%>
</td>
</tr>
<tr>
<td valign="top">
<label for="FoodDescription">
Description:</label>
</td>
<td>
<%=Html.TextArea("FoodDescription", Model.Food.FoodDescription, 5, 40, new { #maxlength = "50" })%> <%=Html.ValidationMessage("FoodDescription", "*")%>
</td>
</tr>
<tr>
<td valign="top">
<label for="Tags">
Tags:</label>
</td>
<td>
<%=Html.TextArea("Tags", Model.Food.Tags, 5, 40, new { #maxlength = "50" })%> <%=Html.ValidationMessage("Tags", "*")%>
</td>
</tr>
<tr>
<td valign="top">
<label for="Image">
Image:</label>
</td>
<td>
<table>
<tr>
<td>
<%=Html.Image("Img200x200", Model.Food.Img200x200, "Food Image", new { #width = "200", #height = "200" })%>
</td>
</tr>
<tr>
<td>
<div id="browseFile">
<input name="Image" id="Image" type="file" size="45" onchange="document.getElementById('inputTxtFake').value = this.value;"
class="inputImage" />
<!-- fake input to display the path of the selected file : start -->
<input name="inputTxtFake" type="text" id="inputTxtFake" />
<!-- fake input to display the path of the selected file : end -->
</div>
<input id="ClonedFromFoodID" name="ClonedFromFoodID" type="hidden" value="<%=Model.Food.ClonedFromFoodID %>" />
<input id="IsUserFood" name="IsUserFood" type="hidden" value="<%=Model.Food.IsUserFood %>" />
<input id="Img200x200" name="Img200x200" type="hidden" value="<%=Model.Food.Img200x200 %>" />
</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
<script language="javascript" type="text/javascript">
$(document).ready(function() {
var isUserFood = '<%=Model.Food.IsUserFood %>';
var hasClones = '<%=Model.Food.HasClones %>';
var isClone = '<%=Model.Food.IsClone %>';
var canClone = window.location.toString().toLowerCase().indexOf("/edit") > -1;
var gettingCloned = window.location.toString().toLowerCase().indexOf("/clone") > -1
if (hasClones.toLowerCase() == 'true') {
$("#divCloningMessage").html("This food has already been cloned.");
canClone = 'false';
}
originalCreator = '<%=Model.Food.OriginalCreator%>';
clonedFromFoodID = '<%=Model.Food.ClonedFromFoodID%>';
$("#spanOriginalCreatorLabel").html("Original Creator:");
$("#spanOriginalCreator").html(originalCreator);
if (isClone.toLowerCase() == 'true') {
var originalCreator;
$("#spanClonedByLabel").html("Cloned By:");
$("#spanClonedBy").html("WFM Nutritionist");
$("#divCloningMessage").html("This food is cloned from food with id " + clonedFromFoodID + ".");
canClone = 'false';
}
if (canClone == true) {
utility.ui.makeYUIButton("btnCloneThisFood");
$("#btnCloneThisFood-button").click(function() {
var cloneFoodId = '<%=Model.Food.FoodID %>';
var clonedFoodUrl = '<%=Url.Content("~/") %>foods/clone/' + cloneFoodId;
window.location = clonedFoodUrl;
});
$("#divBtnCloneThisFood").show();
}
var clonedFromFoodID = $("#ClonedFromFoodID").val();
if (gettingCloned) {
$("#spanFoodID").html("0");
}
utility.ui.makeYUIButton("btnNewCompany");
checkForBasicFood();
$("#ddlFoodType").change(function() {
checkForBasicFood();
});
$("#btnNewCompany").click(function() {
var btnID, txtNameId, txtDescId, catId, catName, eleToUpdateId, uiUpdateType;
btnID = "btnNewCompany";
txtNameId = $("input[boundbutton='" + btnID + "']").attr('id');
txtDescId = $("textarea[boundbutton='" + btnID + "']").attr('id');
catId = $("input[boundbutton='" + btnID + "']").attr('catId');
eleToUpdateId = $("input[boundbutton='" + btnID + "']").attr('updateEle');
catName = $("input[boundbutton='" + btnID + "']").attr('catName');
uiUpdate = $("input[boundbutton='" + btnID + "']").attr('uiUpdateType');
if ($("#" + txtNameId).val() == "")
$("div[boundButton='" + btnID + "']").fadeIn().fadeOut(10000);
else {
var subCategory = {
categoryId: catId,
parentCategoryId: $("#ddlFoodType").val(),
categoryLevel: 2,
categoryName: $("#" + txtNameId).val(),
categoryDescription: $("#" + txtDescId).val(),
categoryIconPath: "",
sortOrder: 0
};
// Initializing food helper
foodHelper.init('<%= Url.Content("~/") %>');
foodHelper.addSubCategory(subCategory, {
updateElementId: eleToUpdateId,
updateDropdownID: "ddlCompany",
categoryName: catName,
messageDivId: catName + "Message",
catNameTxtBoxId: txtNameId,
catDescTxtBoxId: txtDescId,
uiUpdateType: uiUpdate
});
}
});
});
function checkForBasicFood() {
if ($("#ddlFoodType").val() == 1444 || $("#ddlFoodType").val() == -1) { // Bad: hard coding value
$("#rowCompany").hide();
$("#rowAddCompany").hide();
}
else {
var selectedFoodType = $("#ddlFoodType").val();
if (selectedFoodType == 688) {
$("#spanCompany").html("Restaurant Brand:");
$("#spanAddCompany").html("Add a New Restaurant Brand:");
$("#divAddCompanyError").html("Please enter name for Restaurant Brand.");
}
else if (selectedFoodType == 689) {
$("#spanCompany").html("Store Brand:");
$("#spanAddCompany").html("Add a New Store Brand:");
$("#divAddCompanyError").html("Please enter name for Store Brand.");
}
$("#rowCompany").show();
$("#rowAddCompany").show();
}
}
</script>
Personally, I think it is very odd to have properties of type SelectList and List<CheckBoxInfo> in your view model class. Most viewmodels should contain properties of very basic types, like string and int. The way you have, makes it very hard to debug & identify your problems but I would go and say that most likely the default model binder doesn't know how to bind values from HTML controls to your viewmodel props.
I would advise looking into building a custom modelbinder or rewriting the view model class. Or rewriting the app as a whole (but I guess that's not an option).
HTH
Certain property name don't match with actual names............need to modify

Resources