2010-08-31 6 views
46

HTML5 parece apoyar una nueva gama de input fields para things such as:métodos auxiliares ASP.NET MVC HTML para tipos de entrada nueva HTML5

  • Números
  • direcciones de correo electrónico
  • Colores
  • URL
  • Rango numérico (a través de un control deslizante)
  • Fechas
  • cajas de búsqueda

Alguien ha implementado HtmlHelper métodos de extensión para ASP.NET MVC que genera estos todavía? Es posible hacer esto utilizando una sobrecarga que acepta htmlAttributes, tales como:

Html.TextBoxFor(model => model.Foo, new { type="number", min="0", max="100" }) 

Pero eso no es tan buena (o typesafe) como:

Html.NumericInputFor(model => model.Foo, min:0, max:100) 

Respuesta

51

Sólo una señala que muchos de estos ahora están incorporados en MVC4 utilizando el atributo DataType.

A partir de this work item puede utilizar:

public class MyModel 
{ 
    // Becomes <input type="number" ... > 
    public int ID { get; set; } 

    // Becomes <input type="url" ... > 
    [DataType(DataType.Url)] 
    public string WebSite { get; set; } 

    // Becomes <input type="email" ... > 
    [DataType(DataType.EmailAddress)] 
    public string Email { get; set; } 

    // Becomes <input type="tel" ... > 
    [DataType(DataType.PhoneNumber)] 
    public string PhoneNumber { get; set; } 

    // Becomes <input type="datetime" ... > 
    [DataType(DataType.DateTime)] 
    public DateTime DateTime { get; set; } 

    // Becomes <input type="date" ... > 
    [DataType(DataType.Date)] 
    public DateTime Date { get; set; } 

    // Becomes <input type="time" ... > 
    [DataType(DataType.Time)] 
    public DateTime Time { get; set; } 
} 
+0

@Drew: cree que la fecha, la fecha y hora están incluidas en ese elemento de trabajo (sin duda son parte de la versión de mvc4). ¿Por qué dices lo contrario? –

+0

me malinterpretó el comentario: _We necesita hacer esto de forma automática por teléfono, URL, correo electrónico, fecha y hora, la fecha, la hora y number._ me he vinculado a los documentos y extendieron el código de ejemplo. Buen hallazgo, gracias. –

9

encanta cuando se puede conducir este tipo de cosas fuera del modelo !! Adorné mis modelos con [DataType(DataType.PhoneNumber)], y todos menos uno funcionaron.

Me di cuenta de la manera difícil que @Html.TextBoxFor no rinde el type="<HTML5 type>" pero @Html.EditorFor lo hace. Tiene sentido que supongo ahora que lo pienso, pero publicar esto quizá salvar a otros frustrantes los pocos minutos que acabo de perder;)

+0

En mi caso no funciona con TextBoxFor y EditorFor en IE y Chrome, ¿qué es lo que piensas? – QMaster

10

Lo que no me gusta de DataTypes atributos es que u tiene que utilizar EditorFor en la vista. Entonces, no puede usar htmlAttributes para decorar su etiqueta. Hay otras soluciones pero prefiero de esta manera.

En este ejemplo, solo extendí la firma que uso más.

Así que en la clase:

using System.Linq.Expressions; 
namespace System.Web.Mvc.Html 
{ 
    public static class HtmlExtensions 
    { 
     public static MvcHtmlString EmailFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression, Object htmlAttributes) 
     { 
      MvcHtmlString emailfor = html.TextBoxFor(expression, htmlAttributes); 
      return new MvcHtmlString(emailfor.ToHtmlString().Replace("type=\"text\"", "type=\"email\"")); 
     } 
    } 
} 

Como se ve acabo de cambiar el tipo = "text" para el tipo = "email" y entonces puedo usar en mi opinión:

<div class="form-group">    
     @Html.LabelFor(m => m.Email, new { @class = "col-lg-2 control-label" }) 
     <div class="col-lg-10"> 
      @Html.EmailFor(m => m.Email, new { @class = "form-control", placeholder = "Email" }) 
      @Html.ValidationMessageFor(m => m.Email)         
     </div>    
    </div> 

Y la fuente html da:

<div class="form-group">    
    <label class="col-lg-2 control-label" for="Email">Email</label> 
    <div class="col-lg-10"> 
     <input class="form-control" data-val="true" data-val-required="The Email field is required." id="Email" name="Email" placeholder="Email" type="email" value="" /> 
     <span class="field-validation-valid" data-valmsg-for="Email" data-valmsg-replace="true"></span>         
    </div>    
</div> 
+2

Para su información, de hecho, puede usar atributos html con EditorFor, pero tendría que escribir su propia plantilla para ello. Lo cual es mucho menos intrusivo que escribir un nuevo helper Html. –

+0

Estoy de acuerdo con usted y vi algunos comentarios sobre el uso de plantillas. Lamentablemente, ahora mismo estoy en la etapa de aprendizaje en MVC y no me tomé el tiempo para mirar las plantillas Editor y Pantalla. – RPAlbert

+4

A partir de MVC 5.1, puede usar atributos HTML con etiquetas EditorFor. – Yecats

6

La manera más fácil es simplemente agregar type = "Email" como un atributo html. Anula el tipo predeterminado = "texto".He aquí un ejemplo con HTML5 validador también:

@Html.TextBox("txtEmail", "", new { placeholder = "email here", @required = "", @type="email" }) 
+0

Eso es más o menos lo que muestro en la pregunta original. Estaba buscando una solución más segura. –

+0

Hola @Drew: tienes toda la razón, cuando leí las respuestas, había olvidado tu pregunta original, ¡lo siento! – user1191559

+0

Sin preocupaciones. Su código definitivamente funciona, pero me gustaría evitar el uso de tipos anónimos, tanto para el rendimiento como porque el compilador no los verifica por su corrección. –

0

encontré mi auto querer el número spinner que se obtiene al utilizar <input type='number' /> de un HtmlHelper, y terminó la solución de mi auto.

De manera similar a la respuesta Html.Email de RPAlbert Para la respuesta anterior, comencé a usar el Html.TextBoxFor normal, pero luego usé LinqToXml para modificar el código HTML en lugar de simplemente usar una cadena para reemplazar.

La ventaja de comenzar con el Html.TextBoxFor es que se puede utilizar de todas las cosas de validación del lado del cliente que MVC hace por usted. En este caso estoy usando los valores de la data-val-range atributos para definir los atributos min/max necesarios para restringir el spinner.

public static HtmlString SpinnerFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object htmlAttributes) 
{ 
    XDocument _xml = XDocument.Parse(html.TextBoxFor(expression, htmlAttributes).ToString()); 
    XElement _element = _xml.Element("input"); 

    if (_element != null) 
    { 
     _element.SetAttributeValue("type", "number"); 

     if (_element.Attribute("data-val-range-max") != null) 
      _element.SetAttributeValue("max", _element.Attribute("data-val-range-max").Value); 

     if (_element.Attribute("data-val-range-min") != null) 
      _element.SetAttributeValue("min", _element.Attribute("data-val-range-min").Value); 
    } 

    return new HtmlString(_xml.ToString()); 
} 

A continuación, utilizarlo como lo haría con cualquier otra HtmlHelper en sus puntos de vista:

@Html.SpinnerFor(model => model.SomeNumber, new { htmlAttribute1 = "SomeValue" })

Esta fue mi implementación de todos modos, desde que pregunta que yo puedo ver que quería:

@Html.NumericInputFor(model => model.Foo, min:0, max:100)

sería muy sencillo de ajustar mi método para hacer esto de la siguiente manera:

public static HtmlString NumericInputFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, int min, int max) 
{ 
    XDocument _xml = XDocument.Parse(html.TextBoxFor(expression, htmlAttributes).ToString()); 
    XElement _element = _xml.Element("input"); 

    if (_element != null) 
    { 
     _element.SetAttributeValue("type", "number"); 
     _element.SetAttributeValue("min", min); 
     _element.SetAttributeValue("max", max); 
    } 

    return new HtmlString(_xml.ToString()); 
} 

Básicamente todo lo que he hecho es cambiarle el nombre y proporcionar min/max como argumentos en lugar de obtenerlos de los atributos de DataAnnotación.

Espero que ayude!

Cuestiones relacionadas