Am new to MVC, am am trying to apply CSS styles to Html.DisplayFor helper inside my template file: Shared>>EditorTemplate>>Contacts.cshtml. Below is my code:
#model People.Contacts
<div>
#Html.DisplayNameFor(m => m.Name) <span class="myclass">#Html.DisplayFor(m => m.FirstName) #Html.DisplayFor(m => m.LastName)</span></div>
and my css class outside this template looks like this:
.myclass{font:italic bold;}
Html.DisplayFor does not support passing HTML attributes, including class/style. At it's most basic it merely renders the value, without any HTML, and with editor/display templates, it just renders whatever's in the template.
First, if you have EditorTemplates\Contacts.cshtml, that will actually never be used by DisplayFor. For DisplayFor you need a separate template in Views\Shared\DisplayTemplates. As its name implies EditorTemplates is used by EditorFor.
Either DisplayFor or EditorFor are basically the same as calling Html.Partial. There's just some additional logic to deal with a specific model property and look by default in DisplayTemplates/EditorTemplates for the view. That said, you can pass additional data to them the same as you would with a partial, via ViewData.
For example, if you were to call #Html.DisplayFor(m => m.FirstName, new { #class = "myclass" }), then nothing would happen by default, but you would have a value of "myclass" in ViewData["class"]. You could then use that to modify a part of your template. For example:
Views\Shared\DisplayTemplates\Contacts.cshtml
<span #(ViewData["class"] != null ? "class='" + ViewData["class"] + "'" : string.Empty)>
#ViewData.TemplateInfo.FormattedModelValue
</span>
That checks to see if ViewData["class"] has a value, and if so, adds a class attribute with that value to the span.
As a different solutions you can use Html.DisplayFor in <Label> tag
<label class="control-label"> #Html.DisplayNameFor(p => p.HeadLine)</label>
Related
When I look at an older MVC project, the following code would render a textbox with the propriate styling:
#Html.EditorFor(model => model.Title, new { htmlAttributes = new { #class = "form-control" } })
But now that JQueryUI is being used instead of Bootstrap, I had to manually add Bootstrap again and added the same line to my code, but the class won't render.
The only way to make it work it seems is using the:
#Html.TextBoxFor(model => model.License, new { #class = "form-control" })
HTML helper.
Is there a big difference between EditorFor and TextBoxFor and if it is important to use EditorFor instead of TextBoxFor, how could I add the Bootstrap class form-control to the rendered input by the EditorFor HTML helper? And what is causing this situation that the class won't be rendered on the input element with the HTML helper?
TextBoxFor: Is always render like an input textbox irrespective datatype of the property which is getting bind with the control. It creates a text input like this : <input type="text" />
EditorFor: It renders HTML markup based on the datatype of the property.
Both will be generate the same markup.
You can also see explanations in this post: https://stackoverflow.com/a/4826185/3401842
In .Net MVC we use Editor Templates to output HTML. So in a View we write something like below and the Editor Template for String (Description is a string object) outputs the correct HTML and controls for the string type:
#Html.EditorFor(model => model.Entity.Description)
I want to create an Editor Template that is able to use\recreate the Lambda expression that I used in the view i.e. model.Entity.Description. In the Editor Template I can retrieve the property name in this case Description however I'd like to be able to retrieve the Lambda expression in the Editor Template that I used in the View i.e. model => model.Entity.Description
An example Editor Template is below - I want to replace MYLAMBDAEXPRESSIONHERE with the relevant expression dynamically i.e. model => model.Entity.Description:
#model IDictionary Fields //Or some object that also contains the lambda expression
#using System.Collections;
#using System.Collections.Generic;
#using Mallon.Core.Artifacts;
#{
var fieldName = ViewData.TemplateInfo.HtmlFieldPrefix;
FieldAccessOptionality access = (FieldAccessOptionality)Model[fieldName];
switch(access)
{
case FieldAccessOptionality.None:
break;
case FieldAccessOptionality.Mandatory:
<div class="editor-label">
#Html.LabelFor(MYLAMBDAEXPRESSIONHERE)
</div>
<div class="editor-field">
#Html.EditorFor(MYLAMBDAEXPRESSIONHERE)
#Html.ValidationMessageFor(MYLAMBDAEXPRESSIONHERE)
</div>
break;
}
}
You cannot access the lambda expression in the template but you can use the ModelMetadata in order to obtain further information. For example,
#ViewData.ModelMetadata.PropertyName
gives you the property name. In your example, "Description".
Am using MVC 4 and want to maintain some values on postback, so they're going into hidden fields. In essence:
#using (Html.BeginForm())
{
Html.HiddenFor(model => model.EventId);
Html.HiddenFor(model => model.paymentMethodId);
}
But the hidden fields are not appearing in the rendered markup and are therefore - obviously - missing on postback.
You need to add a #, #Html.HiddenFor(). Otherwise you're just executing the helper method, but not actually doing anything with the output.
As dombenoit says, missing the "#" directive, and also need to remove the ";" from the end of each line for some reason, so the corrected code sample looks like:
#using (Html.BeginForm())
{
#Html.HiddenFor(model => model.EventId)
#Html.HiddenFor(model => model.paymentMethodId)
}
Now renders the hidden fields as expected.
Asp.net Mvc3 ads some custom attributes like "data-val-required" on input elements to perform validation. I know all theory behind this, how it works.
What i want to know is :
When I create my form inside " #using (Html.BeginForm())" it produces custom attributes, but it doesn't create those attributes when i place my form between plain "<form>" tag.
below is a demo i have created to demonstrate what iam saying
Razor Code, form inside BefingForm()
#using (Html.BeginForm()) {
#Html.EditorFor(model => model.EmailAddress)
#Html.ValidationMessageFor(model => model.EmailAddress)
}
generated Html contains "data-val-required" as attribute shown below
<input type="text" value="" data-val-required="The Email Address field is required." data-val-email="my message">
Razor Code Form inside pure Html Tag
<form action="/Account/Register" method="post">
#Html.EditorFor(model => model.EmailAddress)
#Html.ValidationMessageFor(model => model.EmailAddress)
</form>
generated Html doesnt contain "data-val-required" attribute shown below
<input type="text" value="" gtbfieldid="44">
My question is how can i ask MVC to add those attributes even form is placed in side pure html tags
I believe BeginForm method internally assigns a formcontext object to viewCotnext's property FormContext. If you do not want to use plain html form tags you have to do it manually like
<%
this.ViewContext.FormContext = new FormContext();
%>
and in razor it would probably be
#{
this.ViewContext.FormContext = new FormContext();
}
Problem here is that internally Html.BeginForm is flagged by Html.EnableClientValidation() to create FormContext that will store client-side validation metadata. Now, any HTML helper method that renders validation message also registers appropriate client-side validation metadata in FormContext. The result is what you get if you use helper. However, if you try to use HTML syntax and not helpers, the FormContext is never registered and therefore your validation is never added.
Regards,
Huske
I have a file in my view folder Users called UserViewControl.cshtml.
My code in the actual view (Users.cshtml) is:
#Html.RenderPartial("RegisterViewControl")
Error:The best overloaded method match for 'System.Web.WebPages.WebPageExecutingBase.Write(System.Web.WebPages.HelperResult)' has some invalid arguments
I do not want to type the path fully like this as the whole view folders might move in the future:
#Html.RenderPartial("~/Views/Users/RegisterViewControl.cshtml")
Code in RegisterViewControl.cshtml:
#model SampleMVC.Web.ViewModels.RegisterModel
#using (Html.BeginForm("Register", "Auth", FormMethod.Post, new { Id = "ERForm" }))
{
#Html.TextBoxFor(model => model.Name)
#Html.TextBoxFor(model => model.Email)
#Html.PasswordFor(model => model.Password)
}
This is a form that will be submitted by ajax, but I want all the validation from the viewmodel.
It should be like this:
#{Html.RenderPartial("RegisterViewControl");}
And that's because the RenderPartial extension method doesn't return anything. It writes directly to the output. In aspx you use it like this:
<% Html.RenderPartial("RegisterViewControl"); %>
instead of:
<%= Html.RenderPartial("RegisterViewControl") %>
So the same rules apply for razor.
You could alternatively use
#Html.Partial("RegisterViewControl")
I had this issue as well and got this directly from Scott Guthrie's blog post:
using #Html.RenderPartial() from a Razor view doesnt work.
Rather than call Html.RenderPartial() use just
#Html.Partial("partialname")
That returns a string and will work.
Alternatively, if you really want to use the void return method you
can use this syntax:
#{Html.RenderPartial("partialName")}
But #Html.Partial() is the cleanest.
The link for this is: http://weblogs.asp.net/scottgu/archive/2010/12/30/asp-net-mvc-3-layouts-and-sections-with-razor.aspx