Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EditorFor() and html properties

People also ask

What does HTML EditorFor do?

The Html. Editor() or Html. EditorFor() extension methods generate HTML elements based on the data type of the model object's property.

What are the advantages of the HTML EditorFor () method?

The advantages of EditorFor is that your code is not tied to an <input type="text" . So if you decide to change something to the aspect of how your textboxes are rendered like wrapping them in a div you could simply write a custom editor template ( ~/Views/Shared/EditorTemplates/string.

How do I add an EditorFor style?

EditorFor does not allow for styling as there are no parameters for additional attributes. The reason for this is because the EditorFor doesn't always generate a single element as it can be overridden. To style a specific type of element you need to use the specific editor you want to use.

What is HTML editor in MVC?

The HtmlEditor component is a client-side WYSIWYG text editor. The editor allows users to format text and integrate media elements into documents. The result can be exported to HTML or Markdown. Users can edit and customize content using the toolbar that can contain predefined and custom controls.


In MVC3, you can set width as follows:

@Html.TextBoxFor(c => c.PropertyName, new { style = "width: 500px;" })

I solved this by creating an EditorTemplate named String.ascx in my /Views/Shared/EditorTemplates folder:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<string>" %>
<% int size = 10;
   int maxLength = 100;
   if (ViewData["size"] != null)
   {
       size = (int)ViewData["size"];
   }
   if (ViewData["maxLength"] != null)
   {
       maxLength = (int)ViewData["maxLength"];
   }
%>
<%= Html.TextBox("", Model, new { Size=size, MaxLength=maxLength }) %>

In my view, I use

<%= Html.EditorFor(model => model.SomeStringToBeEdited, new { size = 15, maxLength = 10 }) %>

Works like a charm for me!


None of the answers in this or any other thread on setting HTML attributes for @Html.EditorFor were much help to me. However, I did find a great answer at

Styling an @Html.EditorFor helper

I used the same approach and it worked beautifully without writing a lot of extra code. Note that the id attribute of the html output of Html.EditorFor is set. The view code

<style type="text/css">
#dob
{
   width:6em;
}
</style>

@using (Html.BeginForm())
{
   Enter date: 
   @Html.EditorFor(m => m.DateOfBirth, null, "dob", null)
}

The model property with data annotation and date formatting as "dd MMM yyyy"

[Required(ErrorMessage= "Date of birth is required")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd MMM yyyy}")]
public DateTime DateOfBirth { get; set; }

Worked like a charm without writing a whole lot of extra code. This answer uses ASP.NET MVC 3 Razor C#.


May want to look at Kiran Chand's Blog post, he uses custom metadata on the view model such as:

[HtmlProperties(Size = 5, MaxLength = 10)]
public string Title { get; set; }

This is combined with custom templates that make use of the metadata. A clean and simple approach in my opinion but I would like to see this common use case built-in to mvc.


I'm surprised no one mentioned passing it in "additionalViewData" and reading it on the other side.

View (with line breaks, for clarity):

<%= Html.EditorFor(c => c.propertyname, new
    {
        htmlAttributes = new
        {
            @class = "myClass"
        }
    }
)%>

Editor template:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<string>" %>

<%= Html.TextBox("", Model, ViewData["htmlAttributes"])) %>

The problem is, your template can contain several HTML elements, so MVC won't know to which one to apply your size/class. You'll have to define it yourself.

Make your template derive from your own class called TextBoxViewModel:

public class TextBoxViewModel
{
  public string Value { get; set; }
  IDictionary<string, object> moreAttributes;
  public TextBoxViewModel(string value, IDictionary<string, object> moreAttributes)
  {
    // set class properties here
  }
  public string GetAttributesString()
  {
     return string.Join(" ", moreAttributes.Select(x => x.Key + "='" + x.Value + "'").ToArray()); // don't forget to encode
  }

}

In the template you can do this:

<input value="<%= Model.Value %>" <%= Model.GetAttributesString() %> />

In your view you do:

<%= Html.EditorFor(x => x.StringValue) %>
or
<%= Html.EditorFor(x => new TextBoxViewModel(x.StringValue, new IDictionary<string, object> { {'class', 'myclass'}, {'size', 15}}) %>

The first form will render default template for string. The second form will render the custom template.

Alternative syntax use fluent interface:

public class TextBoxViewModel
{
  public string Value { get; set; }
  IDictionary<string, object> moreAttributes;
  public TextBoxViewModel(string value, IDictionary<string, object> moreAttributes)
  {
    // set class properties here
    moreAttributes = new Dictionary<string, object>();
  }

  public TextBoxViewModel Attr(string name, object value)
  {
     moreAttributes[name] = value;
     return this;
  }

}

   // and in the view
   <%= Html.EditorFor(x => new TextBoxViewModel(x.StringValue).Attr("class", "myclass").Attr("size", 15) %>

Notice that instead of doing this in the view, you may also do this in controller, or much better in the ViewModel:

public ActionResult Action()
{
  // now you can Html.EditorFor(x => x.StringValue) and it will pick attributes
  return View(new { StringValue = new TextBoxViewModel(x.StringValue).Attr("class", "myclass").Attr("size", 15) });
}

Also notice that you can make base TemplateViewModel class - a common ground for all your view templates - which will contain basic support for attributes/etc.

But in general I think MVC v2 needs a better solution. It's still Beta - go ask for it ;-)


I think using CSS is the way to go. I wish I could do more with .NET coding, like in XAML, but in the browser CSS is king.

Site.css

#account-note-input { 
  width:1000px; 
  height:100px; 
} 

.cshtml

<div class="editor-label"> 
  @Html.LabelFor(model => model.Note) 
</div> 
<div class="editor-field"> 
  @Html.EditorFor(model => model.Note, null, "account-note-input", null) 
  @Html.ValidationMessageFor(model => model.Note) 
</div>

Joe