ASP.NET MVC HTML вспомогательные методы для новых типов ввода HTML5 - PullRequest
47 голосов
/ 01 сентября 2010

HTML5 поддерживает новый диапазон полей ввода для таких вещей, как :

  • Числа
  • Адреса электронной почты
  • Цвета
  • URL-адреса
  • Числовой диапазон (с помощью ползунка)
  • Даты
  • Поисковые поля

ИмеетКто-нибудь реализовал HtmlHelper методы расширения для ASP.NET MVC, который их генерирует?Это можно сделать, используя перегрузку, которая принимает htmlAttributes, например:

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

Но это не так хорошо (или не безопасно), как:

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

Ответы [ 6 ]

52 голосов
/ 13 мая 2013

Просто предупреждаю, что многие из них теперь включены в MVC4 с помощью атрибута DataType.

Начиная с этот рабочий элемент вы можете использовать:

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; }
}
23 голосов
/ 01 сентября 2010

Ознакомьтесь с ASP.net MVC HTML5 Helpers Toolkit

11 голосов
/ 13 июня 2014

Самый простой способ - просто добавить type = "Email" в качестве атрибута html.Он переопределяет тип по умолчанию = "текст".Вот пример с html5 обязательным валидатором также:

@Html.TextBox("txtEmail", "", new {placeholder = "email...", @type="email", @required = ""})
11 голосов
/ 18 сентября 2013

Что мне не нравится в DataTypes Атрибуты в том, что вам нужно использовать EditorFor в представлении.Тогда вы не можете использовать htmlAttributes для украшения вашего тега.Есть и другие решения, но я предпочитаю этот способ.

В этом примере я только расширил подпись, которую я использую больше всего.

Так в классе:

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\""));
        }
    }
}

Каквы видите, я просто изменил type = "text" для type = "email", а затем я могу использовать в моем представлении:

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

И источник HTML дает:

<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> 
9 голосов
/ 23 июля 2013

Люблю, когда можно отгонять подобные вещи от модели !!Я украсил свои модели [DataType(DataType.PhoneNumber)], и все, кроме одной, сработало.

Я осознал, что @Html.TextBoxFor не рендерит type="<HTML5 type>", а @Html.EditorFor.Имеет смысл, я думаю, теперь, когда я думаю об этом, но опубликовать это, чтобы, возможно, сэкономить другим те разочаровывающие несколько минут, которые я только что потерял;)

2 голосов
/ 01 сентября 2016

Я обнаружил, что хочу получить счетчик чисел, который вы получаете при использовании <input type='number' /> из HtmlHelper, и в итоге решил сам.

По аналогии с приведенным выше ответом RPAlbert's Html.EmailFor, я начал с использования обычного Html.TextBoxFor, но затем я использовал LinqToXml для изменения HTML, а не просто для замены строки.

Преимущество начала работы с Html.TextBoxFor заключается в том, что вы можете использовать все средства проверки на стороне клиента, которые MVC делает для вас. В этом случае я использую значения из атрибутов data-val-range, чтобы установить атрибуты min / max, необходимые для ограничения счетчика.

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());
}

Затем вы будете использовать его так же, как любой другой HtmlHelper в ваших представлениях:

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

В любом случае, это была моя реализация, из твоего вопроса я вижу, что ты хотел:

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

Было бы очень просто настроить мой метод, чтобы сделать это следующим образом:

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());
}

По сути, все, что я сделал, это переименовал его и указал min / max в качестве аргументов, а не получал их из атрибутов DataAnnotation.

Надеюсь, это поможет!

...