net mvc for ejemplo asp html asp.net-mvc editorfor

mvc - html editorfor()



Atributos Html para EditorFor() en ASP.NET MVC (14)

¿Por qué no puedo pasar los atributos html a EditorFor() ? p.ej;

<%= Html.EditorFor(model => model.Control.PeriodType, new { disabled = "disabled", readonly = "readonly" }) %>

No quiero usar metadatos

Actualización : la solución fue llamar esto desde la vista:

<%=Html.EditorFor( model => model.Control.PeriodEndDate, new {Modifiable=model.Control.PeriodEndDateModifiable})%>

y use ViewData["Modifiable"] en mi EditorTemplates / String.ascx personalizado donde tengo alguna lógica de vista que determina si agregará atributos readonly y / o disabled a la entrada. El objeto anónimo pasado a EditorFor() es un parámetro llamado additionalViewData y sus propiedades se pasan a la plantilla del editor en la colección ViewData .


¿Por qué no solo usar

@Html.DisplayFor(model => model.Control.PeriodType)



Aún puedes usar EditorFor. Simplemente pase el estilo / cualquier atributo html como ViewData.

@Html.EditorFor(model => model.YourProperty, new { style = "Width:50px" })

Como EditorFor usa plantillas para representar, puede anular la plantilla predeterminada para su propiedad y simplemente pasar el atributo de estilo como ViewData.

Por lo tanto, a su EditorTemplate le gustaría lo siguiente:

@inherits System.Web.Mvc.WebViewPage<object> @Html.TextBoxFor(m => m, new { @class = "text ui-widget-content", style=ViewData["style"] })


Ahora ASP.Net MVC 5.1 tiene un soporte integrado para ello.

De las notas de la versión

Ahora permitimos pasar atributos HTML en EditorFor como un objeto anónimo.

Por ejemplo:

@Html.EditorFor(model => model, new { htmlAttributes = new { @class = "form-control" }, })


Aquí está la sintaxis del código VB.Net para atributos html en MVC 5.1 EditorFor

@Html.EditorFor(Function(x) x.myStringProp, New With {.htmlAttributes = New With {.class = "myCssClass", .maxlength="30"}}))


En mi caso, estaba tratando de crear una plantilla de editor de entrada de números HTML5 que pudiera recibir atributos adicionales. Un enfoque más ordenado sería escribir tu propio HTML Helper, pero como ya tenía mi plantilla .ascx, opté por este enfoque:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> <input id="<%= Regex.Replace(ViewData.TemplateInfo.GetFullHtmlFieldId(""), @"[/[/]]", "_") %>" name="<%= ViewData.TemplateInfo.HtmlFieldPrefix %>" type="number" value="<%= ViewData.TemplateInfo.FormattedModelValue %>" <% if (ViewData["attributes"] != null) { Dictionary<string, string> attributes = (Dictionary<string, string>)ViewData["attributes"]; foreach (string attributeName in attributes.Keys){%> <%= String.Format(" {0}=/"{1}/"", attributeName, attributes[attributeName])%> <% } } %> />

Este feo bit crea una entrada de tipo de número y busca un Diccionario ViewData con la clave "atributos". Se repetirá en el diccionario agregando sus pares clave / valor como atributos. La Regex en el atributo ID no está relacionada y está ahí porque cuando se usa en una colección, GetFullHtmlFieldId() devuelve una identificación que contiene corchetes [] que normalmente escaparía como caracteres de subrayado.

Esta plantilla se llama así:

Html.EditorFor(m => m.Quantity, "NumberField", new { attributes = new Dictionary<string, string>() { { "class", "txtQuantity" } } }

Verbo, pero funciona Probablemente podría usar el reflejo en la plantilla para usar nombres de propiedades como nombres de atributos en lugar de usar un diccionario.


Establezca la condición usando ViewData en el controlador

ViewData["Modifiable"] = model.recProcessed;

A continuación, utilice esta viewdata en la plantilla del editor para establecer el atributo html del control

@Html.RadioButton(prefix, li.Value, li.Selected, @ViewData["Modifiable"].ToString().ToLower() == "true" ? (object)new { @id = li.Value, @disabled = "disabled" } : new { @id = li.Value })


He estado luchando con el mismo problema hoy para una casilla de verificación que se une a un bool nullable, y como no puedo cambiar mi modelo (no mi código) tuve que encontrar una forma mejor de manejar esto. Es un poco de fuerza bruta, pero debería funcionar en el 99% de los casos que pueda encontrar. Obviamente tendrías que hacer una población manual de atributos válidos para cada tipo de entrada, pero creo que los he obtenido todos para la casilla de verificación.

En mi plantilla de editor Boolean.cshtml:

@model bool? @{ var attribs = new Dictionary<string, object>(); var validAttribs = new string[] {"style", "class", "checked", "@class", "classname","id", "required", "value", "disabled", "readonly", "accesskey", "lang", "tabindex", "title", "onblur", "onfocus", "onclick", "onchange", "ondblclick", "onmousedown", "onmousemove", "onmouseout", "onmouseover", "onmouseup", "onselect"}; foreach (var item in ViewData) { if (item.Key.ToLower().IndexOf("data_") == 0 || item.Key.ToLower().IndexOf("aria_") == 0) { attribs.Add(item.Key.Replace(''_'', ''-''), item.Value); } else { if (validAttribs.Contains(item.Key.ToLower())) { attribs.Add(item.Key, item.Value); } } } } @Html.CheckBox("", Model.GetValueOrDefault(), attribs)


MVC 5.1 y una solución superior (fusionará HtmlAttributes locales y se definirá en EditorTemplates):

Shared / EditorTemplates / String.cshtml:

@Html.TextBoxFor(model => model, new { @class = "form-control", placeholder = ViewData.ModelMetadata.Watermark }.ToExpando().MergeHtmlAttributes(ViewData["htmlAttributes"].ToExpando()))

Extensiones:

public static IDictionary<string, object> MergeHtmlAttributes(this ExpandoObject source1, dynamic source2) { Condition.Requires(source1, "source1").IsNotNull().IsLongerThan(0); IDictionary<string, object> result = source2 == null ? new Dictionary<string, object>() : (IDictionary<string, object>) source2; var dictionary1 = (IDictionary<string, object>) source1; string[] commonKeys = result.Keys.Where(dictionary1.ContainsKey).ToArray(); foreach (var key in commonKeys) { result[key] = string.Format("{0} {1}", dictionary1[key], result[key]); } foreach (var item in dictionary1.Where(pair => !result.ContainsKey(pair.Key))) { result.Add(item); } return result; } public static ExpandoObject ToExpando(this object anonymousObject) { IDictionary<string, object> anonymousDictionary = new RouteValueDictionary(anonymousObject); IDictionary<string, object> expando = new ExpandoObject(); foreach (var item in anonymousDictionary) expando.Add(item); return (ExpandoObject)expando; } public static bool HasProperty(this ExpandoObject expando, string key) { return ((IDictionary<string, object>)expando).ContainsKey(key); }

Uso:

@Html.EditorFor(m => m.PromotionalCode, new { htmlAttributes = new { ng_model = "roomCtrl.searchRoomModel().promoCode" }})


Si no desea usar Metadata, puede usar un [UIHint("PeriodType")] para decorar la propiedad o, si es un tipo complejo, no tiene que decorar nada. EditorFor buscará un archivo PeriodType.aspx o ascx en la carpeta EditorTemplates y lo usará en su lugar.


Solo crea tu propia plantilla para el tipo en Views / Shared / EditorTemplates / MyTypeEditor.vbhtml

@ModelType MyType @ModelType MyType @Code Dim name As String = ViewData("ControlId") If String.IsNullOrEmpty(name) Then name = "MyTypeEditor" End If End Code '' Mark-up for MyType Editor @Html.TextBox(name, Model, New With {.style = "width:65px;background-color:yellow"})

Invoque el editor de su vista con la propiedad del modelo:

@Html.EditorFor(Function(m) m.MyTypeProperty, "MyTypeEditor", New {.ControlId = "uniqueId"})

Perdón por la sintaxis de VB. Así es como rodamos.


EditorFor trabaja con metadatos, por lo que si desea agregar atributos html, siempre puede hacerlo . Otra opción es simplemente escribir una plantilla personalizada y usar TextBoxFor :

<%= Html.TextBoxFor(model => model.Control.PeriodType, new { disabled = "disabled", @readonly = "readonly" }) %>


Actualizar MVC 5.1 ahora es compatible directamente con el siguiente enfoque, por lo que también funciona para el editor incorporado. http://www.asp.net/mvc/overview/releases/mvc51-release-notes#new-features (Es un caso de Gran mente pensando por igual o leyeron mi respuesta :)

Fin de actualización

Si usa su propia plantilla de editor o con MVC 5.1, que ahora admite el siguiente enfoque directamente para los editores integrados.

@Html.EditorFor(modelItem => item.YourProperty, new { htmlAttributes = new { @class="verificationStatusSelect", style = "Width:50px" } })

luego en su plantilla (no es necesario para tipos simples en MVC 5.1)

@Html.TextBoxFor(m => m, ViewData["htmlAttributes"])


Html.TextBoxFor(model => model.Control.PeriodType, new { @class="text-box single-line"})

puedes usar esto; mismo resultado con Html.EditorFor , y puede agregar sus atributos html