When I try to add #Html.HiddenFor(#Model.ID) to my code, I get the following error when access the page:
Compiler Error Message: CS0411: The type arguments for method 'System.Web.Mvc.Html.InputExtensions.HiddenFor(System.Web.Mvc.HtmlHelper, System.Linq.Expressions.Expression>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
I tried reading MSDN, but the documentation is awful (they don't provide a single code example in the documentation for this method.
Here is my View:
#model CustomerService.Entity.Order
#using CustomerService.Entity
#{
ViewBag.Title = "OrderDetails";
}
<h2>
OrderDetails</h2>
#using (Html.BeginForm("HandleSubmit", "Home", FormMethod.Post))
{
<table border="1">
<tr>
<td>
<b>Order #</b>
</td>
<td>
#Model.ID
</td>
</tr>
<tr>
<td>
<b>Description</b>
</td>
<td>
#Model.Description
</td>
</tr>
<tr>
<td>
<b>Salesperson Name</b>
</td>
<td>
#Model.SalespersonName
</td>
</tr>
</table>
<h3>
Line Items</h3>
<input id="btnAddLineItem" type="submit" name="AddLineItem" value="AddLineItem" />
#Html.HiddenFor(#Model.ID)
<table border="1">
<tr>
<td>
<b>Line Item ID</b>
</td>
<td>
<b>Description</b>
</td>
</tr>
#for (int i = 0; i < #Model.LineItems.Count; ++i)
{
<tr>
<td>
#Model.LineItems[i].ID
</td>
<td>
#Model.LineItems[i].Description
</td>
</tr>
}</table>
}
HiddenFor takes an expression.
#Html.HiddenFor( model => model.ID )
HiddenFor method should get an Expression as a parameter not a value:
#Html.HiddenFor(m => m.ID)
Instead of: #Html.HiddenFor(#Model.ID)
Method signature:
HiddenFor<TModel, TProperty>(HtmlHelper<TModel>,
Expression<Func<TModel, TProperty>>)
In plain text you should give an Expression that gets an "instance" of the type of your model(in this case CustomerService.Entity.Order) and returns the desired property(in this case ID)
MSDN
Related
I have defined the following data model in dart file:
#observable List alist = toObservable([{'rel':'self', 'name':'John'},
{'rel':'Father', 'name':'tom'},
{'rel':'Mother', 'name':'jane'}]);
and table in html as follows:
<table id="summaryTable">
<thead>
<tr>
<th>Name</th>
<th>Ralationship to Me</th>
<th>Update History</th>
<th>Remove Relative</th>
</tr>
</thead>
<tr repeat = "{{p in alist}}">
<td>
{{p['name']}}
</td>
<td>
{{p['rel']}}
</td>
<td>
<button on-click="{{updateClicked}}">Update</button>
</td>
<td>
</td>
</tr>
</table>
The table is not getting populated. What should be changed?
It's hard to tell as you didn't provide much code but at least the template is missing in
<tr template repeat="{{p in alist}}">
I would like to take the model as in view?
#model Dictionary<string,List<string>>
<table width="60%">
<tr class="ui-widget-header">
<td>
___Category___
</td>
<td>
___Detail___
</td>
</tr>
<tr>
<td>
#Model.Key
</td>
<td>
#Model.Count
</td>
</tr>
</table>
How could I do this?
here is my view with razor syntax.
Please help me.
Yes you can do it. Below is the sample
#model Dictionary<string,List<string>>
#foreach (KeyValuePair<string, List<string>> pair in Model)
{
<label> #pair.Key</label>
<div>
#foreach(string data in #pair.Value)
{
<span>#data </span>
}
</div>
}
Add #model Dictionary<string,List<string>> to your view (assuming Razor is used).
#model Dictionary<string, List<string>>
#foreach (var group in Model)
{
<h2>#group.Key</h2>
<table>
<tr>
<th>Title</th>
</tr>
#foreach (var aString in group.Value){
<tr>
<td>#aString </td>
</tr>
}
</table>
}
I have a form which is submitted via ajax to the Controller. The Controller collects the data from the Model and then creates a new ViewModel and passes it to the partial view which is then updated on the Client.
The problem is that the textboxes are not cleared out as expected. The message arrives in the View as expected, so it doesn't make sense that the TextBoxes are not cleared out.
Yet it seems to be a browser issue as this is the resulting HTML, which note, does not have anything in the value:
<input id="Address_Address1" name="Address.Address1" type="text" value="" />
Yet the user sees the value that was priorly entered.
Here is the controller:
//Process Order Here
//This should clear out the ViewModel.
order = new OrderViewModel();
order.Message = "Report Added to your cart";
return PartialView("_NewOrderPartial", order);
This is the partial View:
#model NTC.PropertySearch.Models.OrderViewModel
#using (Ajax.BeginForm("NewOrder", "Order", new AjaxOptions { InsertionMode = InsertionMode.Replace, UpdateTargetId = "neworder" }))
{
<div id="neworder">
<table>
<tr>
<th style="width: 300px;">
<h3>Enter property address below</h3>
</th>
<th style="width: 30px;"></th>
<th style="width: 300px;">
<h3>Choose your report below</h3>
</th>
</tr>
<tr>
<td>
<div class="form">
<table>
<tr>
<td>
#Html.LabelFor(m => m.Address.Address1)
</td>
<td>
#Html.TextBoxFor(m => m.Address.Address1)
</td>
<td>
#Html.ValidationMessageFor(m => m.Address.Address1)
</td>
</tr>
<tr>
<td>
#Html.LabelFor(m => m.Address.Address2)
</td>
<td>
#Html.TextBoxFor(m => m.Address.Address2)
</td>
<td>
#Html.ValidationMessageFor(m => m.Address.Address2)
</td>
</tr>
<tr>
<td>
#Html.LabelFor(m => m.Address.City)
</td>
<td>
#Html.TextBoxFor(m => m.Address.City)
</td>
<td>
#Html.ValidationMessageFor(m => m.Address.City)
</td>
</tr>
<tr>
<td>
#Html.LabelFor(m => m.Address.State)
</td>
<td>
#Html.TextBoxFor(m => m.Address.State)
</td>
<td>
#Html.ValidationMessageFor(m => m.Address.State)
</td>
</tr>
<tr>
<td>
#Html.LabelFor(m => m.Address.ZipCode)
</td>
<td>
#Html.TextBoxFor(m => m.Address.ZipCode)
</td>
<td>
#Html.ValidationMessageFor(m => m.Address.ZipCode)
</td>
</tr>
</table>
<input type="submit" value="Add Report" />
#Html.DisplayFor(m=> m.Message)
</div>
</td>
</tr>
</table>
</div>
The reason for this is because the Html helpers such as TextBox are first looking at the ModelState when binding their values and only after that in the View model. This often happens when people attempt to modify/clear some value to the view model in an HttpPost controller action. The corresponding view will use the initial POSTed value and not the value in the view model.
You should clear the ModelState as well in your controller action:
ModelState.Clear();
order = new OrderViewModel();
Alternatively if you do not want to clear the entire ModelState (although in your case this seems to be the case as you are reinitializing the entire view model) you could clear only some properties that you intend to modify:
ModelState.Remove("SomeProperty");
viewModel.SomeProperty = "some new value";
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
I have the following code and I want to put the table headers outside of the #foreach but when i move it outside It no longer sees the closing tag. Thanks
#foreach (var item in Model)
{
<div class="data" ><label for="fullName" >Name: </label>#item.UserName.Replace('.', '')</div>
if (Model.Count > 0)
{
<table class="data">
<tr>
<th>
Work Date
</th>
<th>
Change Details
</th>
<th>
Ip Address
</th>
<th></th>
</tr>
<tr>
<td>
#{
var stringDate = item.WorkDate.ToShortDateString();
}
#Html.DisplayFor(modelItem => stringDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.ChangeDetail)
</td>
<td>
#Html.DisplayFor(modelItem => item.IpAddress)
</td>
</tr>
</table>
}
<br />
<hr />
}
So this is kinda what I'm trying to accomplish, but it keeps giving me errors no matter what way I try it.
<table class="data">
<tr>
<th>
Work Date
</th>
<th>
Change Details
</th>
<th>
Ip Address
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<div class="data" ><label for="fullName" >Name: </label>#item.UserName.Replace('.','')</div>
if (Model.Count > 0)
{
<tr>
<td>
#{
var stringDate = item.WorkDate.ToShortDateString();
}
#Html.DisplayFor(modelItem => stringDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.ChangeDetail)
</td>
<td>
#Html.DisplayFor(modelItem => item.IpAddress)
</td>
</tr>
</table>
}
<br />
<hr />
}
You must have your table closing tag outside of the for each loop.
Short answer: the closing tag </table> has to be placed outside of the foreach loop.
Long answer: You should put the Model.Count > 0 outside of the foreach loop because the moment you enter the code block within the loop, Model.Count > 0 always evaluates to true because you have at least one item.
If – and only if – your model contains any items, you print out the table header. After that, you append one row for each item in Model. Both <table> and </table> have to occur within the same level of nesting.
#if (Model.Count > 0)
{
<table class="data">
<tr>
<th>Date</th>
<th>Change Details</th>
<th>Ip Address</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<div class="data" >
<label for="fullName" >Name: </label>
#item.UserName.Replace('.', ' ')
</div>
#{
var stringDate = item.WorkDate.ToShortDateString();
}
<tr>
<td>#Html.DisplayFor(modelItem => stringDate)</td>
<td>#Html.DisplayFor(modelItem => item.ChangeDetail)</td>
<td>#Html.DisplayFor(modelItem => item.IpAddress)</td>
</tr>
}
</table>
<br />
<hr />
}
You should consider moving the logic (#item.UserName.Replace('.', ' ')) out of the view into the corresponding controller action.