.Net MVC get Lambda expression in Editor Template - asp.net-mvc

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".

Related

EditorFor HTML helper does not take class in MVC

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

How to bind a value to a text box in MVC

I have a problem when I want to bind a value from my model to a textbox, here is my MVC view code:
#Html.TextBox("SellerBroker", model => model.OutOfMarket.BuyerBroker.Name , new { #class = "control-label" })
I want my textbox to have a name or 'SellerBroker' and it's value to come from my model property model => model.OutOfMarket.BuyerBroker.Name and with HTML attributes of class = "control-label". However, I am receiving the following error:
Cannot convert lambda expression to type 'object' because it is not a delegate type
The #Html.TextBox() can be used for generating a textbox with an initial value (one way binding).
If you want to really bind the textbox to your class property (two ways binding), you should use the #Html.TextBoxFor() helper. This method take as parameter a lambda expression, as used in your example.
You can found more details on TextBox helpers at : Html.Textbox VS Html.TextboxFor
Helper #Html.TextBox() does not contain overloard that have lambda parameter. You should use it without lambda like this like #Stephen Muecke advice you:
#Html.TextBox("SellerBroker", Model.OutOfMarket.BuyerBroker.Name , new { #class = "control-label" })
If you want to use lambda you should use #Html.TextBoxFor() helper. But you should change name like this:
#Html.TextBoxFor(model => model.OutOfMarket.BuyerBroker.Name, new { Name = "SellerBroker", #class = "control-label"})

Can I change the width of an EditorFor with data annotations?

There's a few questions on similar topics. However, they don't actually address my issue.
DisplayFormat for TextBoxFor in MVC
Display a formatted date in an EditorFor()
ASP.NET MVC EditorFor DateTime
I've been searching and reading up and cannot find an answer to this.
I'm currently using this to format my input box:
#Html.TextBoxFor(modelItem => item.Quantity, new { style = "width: 30px;" })
From my model, I have the brief data annotation:
[Required, Range(1, 100)]
public int Quantity { get; set; }
So I get this:
When I use
#Html.EditorFor(modelItem => item.Quantity, new { style = "width: 30px;" })
I get this:
What I want is the scroll, but to format the width.
I'm wondering, is there a way to format the width of an EditorFor with data annotations? If not, what is the easiest way to make such a format, to avoid repetition.. bootstrap, css? I'm not happy with the inline styling.
From the comments, your using MVC-4. You cannot pass html attributes to the EditorFor() method unless your using MVC-5.1 or higher (refer the release notes - the section on Bootstrap support for editor templates)
One option is to use the TextBoxFor() method and pass type="number" to render the browsers numeric control
#Html.TextBoxFor(m => m.Quantity, new { type = "number ", style = "width: 30px;" })
Another would be to create a custom EditorTemplate (say _NumericControl.cshtml)
#model System.Int32
#Html.TextBoxFor(m => m, new { type = "number ", style = "width: 30px;" })
and call it using #Html.EditorFor(m => m.Quantity, "_NumericControl")
but this would really only be of any real benefit if the template were also to include other html elements, for example #Html.LabelFor(m => m) and #Html.ValidationMessageFor(m => m) and perhaps even the associated button so that the EditorFor() method renders all elements.

Applying CSS class to Html.DisplayFor (ASP.NET MVC)

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>

How to hide primary key input field using editorfor

Hi I'm using Editorfor() to make a little form that submits view model to the controller. Editorfor() nicely prints input fields of the model but it also prints primary key field. So I want to hide primary key field.
#Html.EditorFor(m=>m.viewmodel)
this is markup that I have.
#Html.HiddenFor(m => m.viewmodel.Id);
#Html.EditorFor(m=>m.viewmodel)
have tried this but does not work. and I wanted to make an approach directly to the model but I'm using EF Designer, so I'm not sure where to begin. Please give me an advice.
Try this:
[HiddenInput(DisplayValue = false)]
public int ProductID { get; set;
Use a custom editor template. For example:
MyViewModel.cshtml (stored in ~/Views/Shared/EditorTemplates folder, structured like a partial view):
#model MyViewModel
#Html.HiddenFor(m => m.Id)
#Html.EditorFor(m => m.Property1)
#Html.TextboxFor(m => m.Property2)
#Html.TextAreaFor(m => m.Property3)
// Whatever else you want in the template
Then you can just call EditorFor on your model in your view that needs to use it and MVC will know to use your custom template:
#Html.EditorFor(m => m.MyViewModel)
To use a custom display template that isn't based on the name of the type, you can also use the [UIHint] attribute as described here: http://www.growingwiththeweb.com/2012/12/aspnet-mvc-display-and-editor-templates.html
Don't create any field for your key attribute. Without a field to check, the validation has nothing to complain about. Later you can supply a value for the primary key in the controller.

Resources