Pregunta

Las versiones preliminares de Asp.Net MVC 2.0 proporcionan ayudantes como

Html.EditorFor(c => c.propertyname)

Si el nombre de la propiedad es una cadena, el código anterior representa un cuadro de texto.

¿Qué sucede si deseo pasar las propiedades MaxLength y Size al cuadro de texto o mi propia propiedad de clase css?

¿Necesito crear una plantilla para cada combinación de tamaño y longitud en mi aplicación? Si es así, eso no hace que las plantillas predeterminadas sean utilizables.

¿Fue útil?

Solución 11

Escribí una entrada de blog para responder mi propia pregunta

Agregar compatibilidad con atributos html para plantillas - ASP.Net MVC 2.0 Beta

Otros consejos

En MVC3, puede establecer el ancho de la siguiente manera:

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

Resolví esto creando un EditorTemplate llamado String.ascx en mi carpeta / Views / Shared / EditorTemplates:

<%@ 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 }) %>

En mi opinión, uso

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

¡Funciona como un encanto para mí!

Ninguna de las respuestas en este o cualquier otro hilo sobre la configuración de atributos HTML para @ Html.EditorFor fue de mucha ayuda para mí. Sin embargo, encontré una gran respuesta en

Diseño de un @ Html.EditorFor helper

Utilicé el mismo enfoque y funcionó a la perfección sin escribir mucho código extra. Tenga en cuenta que el atributo id de la salida html de Html.EditorFor está establecido. El código de vista

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

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

La propiedad del modelo con anotación de datos y formato de fecha como " dd MMM aaaa "

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

Funcionó de maravilla sin escribir un montón de código extra. Esta respuesta usa ASP.NET MVC 3 Razor C #.

Puede querer mirar Publicación del blog de Kiran Chand , utiliza metadatos personalizados en el modelo de vista como:

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

Esto se combina con plantillas personalizadas que utilizan los metadatos. Un enfoque limpio y simple en mi opinión, pero me gustaría ver este caso de uso común integrado en mvc.

Me sorprende que nadie haya mencionado pasarlo en " adicionalViewData " y leerlo al otro lado.

Vista (con saltos de línea, para mayor claridad):

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

Plantilla del editor:

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

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

El problema es que su plantilla puede contener varios elementos HTML, por lo que MVC no sabrá a cuál aplicar su tamaño / clase. Tendrás que definirlo tú mismo.

Haga que su plantilla se derive de su propia clase llamada 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
  }

}

En la plantilla puede hacer esto:

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

En su opinión, usted hace:

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

El primer formulario representará la plantilla predeterminada para la cadena. El segundo formulario representará la plantilla personalizada.

La sintaxis alternativa utiliza una interfaz fluida:

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) %>

Observe que en lugar de hacer esto en la vista, también puede hacerlo en el controlador, o mucho mejor en 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) });
}

Observe también que puede hacer que la clase TemplateViewModel base, un terreno común para todas sus plantillas de vista, que contendrá soporte básico para atributos / etc.

Pero en general creo que MVC v2 necesita una mejor solución. Todavía es Beta, ve a pedirlo ;-)

Creo que usar CSS es el camino a seguir. Desearía poder hacer más con la codificación .NET, como en XAML, pero en el navegador CSS es el rey.

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

Al igual que en MVC 5, si desea agregar cualquier atributo, simplemente puede hacerlo

 @Html.EditorFor(m => m.Name, new { htmlAttributes = new { @required = "true", @anotherAttribute = "whatever" } })

Información encontrada en este blog

Puede definir atributos para sus propiedades.

[StringLength(100)]
public string Body { get; set; }

Esto se conoce como System.ComponentModel.DataAnnotations. Si no puede encontrar el ValidationAttribute que necesita, siempre puede definir atributos personalizados.

Saludos cordiales, Carlos

Puede que esta no sea la solución más ingeniosa, pero es sencilla. Puede escribir una extensión a la clase HtmlHelper.EditorFor. En esa extensión, puede proporcionar un parámetro de opciones que escribirá las opciones en ViewData para el ayudante. Aquí hay un código:

Primero, el método de extensión:

public static MvcHtmlString EditorFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, TemplateOptions options)
{
    return helper.EditorFor(expression, options.TemplateName, new
    {
        cssClass = options.CssClass
    });
}

A continuación, el objeto de opciones:

public class TemplateOptions
{
    public string TemplateName { get; set; }
    public string CssClass { get; set; }
    // other properties for info you'd like to pass to your templates,
    // and by using an options object, you avoid method overload bloat.
}

Y finalmente, aquí está la línea de la plantilla String.ascx:

<%= Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, new { @class = ViewData["cssClass"] ?? "" }) %>

Francamente, creo que esto es sencillo y claro para la pobre alma que tiene que mantener su código en el futuro. Y es fácil de ampliar para varios otros fragmentos de información que le gustaría pasar a sus plantillas. Me está funcionando bien hasta ahora en un proyecto en el que trato de incluir todo lo que puedo en un conjunto de plantillas para ayudar a estandarizar el html circundante, a la http://bradwilson.typepad.com/blog/2009/10/ aspnet-mvc-2-templates-part-5-master-page-templates.html .

No sé por qué no funciona para Html.EditorFor pero probé TextBoxFor y funcionó para mí.

@Html.TextBoxFor(m => m.Name, new { Class = "className", Size = "40"})

... y también funciona la validación.

En mi práctica, descubrí que lo mejor es usar EditorTemplates con solo un HtmlHelper, TextBox, que es en la mayoría de los casos. Si quiero una plantilla para una estructura html más compleja, escribiré un HtmlHelper separado.

Dado que podemos pegar todo el objeto ViewData en lugar de htmlAttributes del TextBox. Además, podemos escribir un código de personalización para algunas de las propiedades de ViewData si necesitan un tratamiento especial:

@model DateTime?
@*
    1) applies class datepicker to the input;
    2) applies additionalViewData object to the attributes of the input
    3) applies property "format" to the format of the input date.
*@
@{
    if (ViewData["class"] != null) { ViewData["class"] += " datepicker"; }
    else { ViewData["class"] = " datepicker"; }
    string format = "MM/dd/yyyy";
    if (ViewData["format"] != null)
    {
        format = ViewData["format"].ToString();
        ViewData.Remove("format");
    }
}

@Html.TextBox("", (Model.HasValue ? Model.Value.ToString(format) : string.Empty), ViewData)

A continuación se muestran ejemplos de la sintaxis en la vista y el html resultante:

@Html.EditorFor(m => m.Date)
<input class="datepicker" data-val="true" data-val-required="&amp;#39;Date&amp;#39; must not be empty." id="Date" name="Date" type="text" value="01/08/2012">
@Html.EditorFor(m => m.Date, new { @class = "myClass", @format = "M/dd" })
<input class="myClass datepicker" data-val="true" data-val-required="&amp;#39;Date&amp;#39; must not be empty." id="Date" name="Date" type="text" value="1/08">

Porque la pregunta es para EditorFor no TextBoxFor La sugerencia de WEFX no funciona.

Para cambiar cuadros de entrada individuales, puede procesar la salida del método EditorFor:

<%: new HtmlString(Html.EditorFor(m=>m.propertyname).ToString().Replace("class=\"text-box single-line\"", "class=\"text-box single-line my500pxWideClass\"")) %>

También es posible cambiar TODOS sus EditorFors ya que resulta que MVC establece la clase de EditorFor cuadros de texto con .text-box , por lo tanto, puede anular este estilo, en su hoja de estilo o en la página.

.text-box {
    width: 80em;
}

Además, puede establecer el estilo para

input[type="text"] {
    width: 200px;
}
  • esto anula .text-box y cambiará todos los cuadros de texto de entrada, EditorFor o de otro modo.

También tuve problemas para configurar el ancho de TextBox en MVC3, mientras que configurar el atributo Clsss funcionó para el control TextArea pero no para el control TextBoxFor o el control EditorFor:

Intenté seguir & amp; eso funcionó para mí:

 @ Html.TextBoxFor (model = & Gt; model.Title, new {Class = & Quot; textBox & Quot ;, style = & Quot; ancho: 90%; & Quot;} )

también en este caso Las validaciones funcionan perfectamente.

Una forma de evitarlo es tener delegados en el modelo de vista para manejar la impresión de representaciones especiales como esta. He hecho esto para una clase de paginación, expongo una propiedad pública en el modelo Func<int, string> RenderUrl para tratarla.

Así que defina cómo se escribirá el bit personalizado:

Model.Paging.RenderUrl = (page) => { return string.Concat(@"/foo/", page); };

Salida de la vista para la clase Paging:

@Html.DisplayFor(m => m.Paging)

... y para la vista <=> real:

@model Paging
@if (Model.Pages > 1)
{
    <ul class="paging">
    @for (int page = 1; page <= Model.Pages; page++)
    {
        <li><a href="@Model.RenderUrl(page)">@page</a></li>
    }
    </ul>
}

Podría verse como una complicación excesiva, pero uso estos buscapersonas en todas partes y no podía soportar ver el mismo código repetitivo para que se procesen.

ACTUALIZACIÓN: hm, obviamente esto no funcionará porque el modelo se pasa por valor, por lo que los atributos no se conservan; pero dejo esta respuesta como una idea.

Otra solución, creo, sería agregar sus propios ayudantes TextBox / etc, que verificarán sus propios atributos en el modelo.

public class ViewModel
{
  [MyAddAttribute("class", "myclass")]
  public string StringValue { get; set; }
}

public class MyExtensions
{
  public static IDictionary<string, object> GetMyAttributes(object model)
  {
     // kind of prototype code...
     return model.GetType().GetCustomAttributes(typeof(MyAddAttribute)).OfType<MyAddAttribute>().ToDictionary(
          x => x.Name, x => x.Value);
  }
}

<!-- in the template -->
<%= Html.TextBox("Name", Model, MyExtensions.GetMyAttributes(Model)) %>

Este es más fácil pero no tan conveniente / flexible.

Esta es la forma más limpia y elegante / simple de obtener una solución aquí.

Publicación de blog brillante y sin excesos desordenados al escribir métodos personalizados de extensión / ayuda como un profesor loco.

http: // geekswithblogs.net/michelotti/archive/2010/02/05/mvc-2-editor-template-with-datetime.aspx

Realmente me gustó la respuesta de @tjeerdans que utiliza el EditorTemplate llamado String.ascx en la carpeta / Views / Shared / EditorTemplates. Parece ser la respuesta más directa a esta pregunta. Sin embargo, quería una plantilla con la sintaxis de Razor. Además, parece que MVC3 usa la plantilla String por defecto (vea la pregunta de StackOverflow & Quot; la plantilla de visualización mvc para cadenas se utiliza para enteros ") por lo que debe configura el modelo como objeto en lugar de cadena. Mi plantilla parece estar funcionando hasta ahora:

@model object 

@{  int size = 10; int maxLength = 100; }

@if (ViewData["size"] != null) {
    Int32.TryParse((string)ViewData["size"], out size); 
} 

@if (ViewData["maxLength"] != null) {
    Int32.TryParse((string)ViewData["maxLength"], out maxLength); 
}

@Html.TextBox("", Model, new { Size = size, MaxLength = maxLength})

¡Lo resolví!
Para Razor la sintaxis es:
@Html.TextAreaFor(m=>m.Address, new { style="Width:174px" }) esto ajusta el ancho del área de texto al ancho que definí en el parámetro de estilo.
Para ASPx, la sintaxis es:
<%=Html.TextAreaFor(m => m.Description, new { cols = "20", rows = "15", style="Width:174px" })%>
esto hará el truco

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top