用于新 HTML5 输入类型的 ASP.NET MVC HTML 帮助器方法

发布于 2024-09-16 22:57:14 字数 660 浏览 20 评论 0 原文

HTML5 似乎支持 输入字段 .org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#states-of-the-type-attribute" rel="noreferrer">诸如 :

  • 数字
  • 电子邮件地址
  • 颜色
  • URL
  • 数字范围(通过滑块)
  • 日期
  • 搜索框

有人为生成这些内容的 ASP.NET MVC 实现了 HtmlHelper 扩展方法吗?可以使用接受 htmlAttributes 的重载来做到这一点,例如:

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

但这并不像以下那样好(或类型安全):

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

HTML5 appears to support a new range of input fields for things such as:

  • Numbers
  • Email addresses
  • Colors
  • URLs
  • Numeric range (via a slider)
  • Dates
  • Search boxes

Has anyone implemented HtmlHelper extension methods for ASP.NET MVC that generates these yet? It's possible to do this using an overload that accepts htmlAttributes, such as:

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

But that's not as nice (or typesafe) as:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

打小就很酷 2024-09-23 22:57:14

请注意,其中许多现在已通过使用 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; }
}

Just a heads up that many of these are now incorporated into MVC4 by using the DataType attribute.

As of this work item you can use:

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; }
}
油焖大侠 2024-09-23 22:57:14

最简单的方法是简单地添加 type="Email" 作为 html 属性。它覆盖默认的 type="text"。下面是一个带有 html5 所需验证器的示例:

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

Easiest way is to simply add type="Email" as an html attribute. It overrides the default type="text". Here is an example with a html5 required validator also:

@Html.TextBox("txtEmail", "", 
    new { placeholder = "email address", 
          @type="email", 
          @required = ""
    })
无声情话 2024-09-23 22:57:14

我不喜欢 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> 

What i don't like about DataTypes Attributes is that u have to use EditorFor in the view. Then, you can't use htmlAttributes to decorate your tag. There are other solutions but i prefer this way.

In this example i only extended the signature i use the most.

So in the class:

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

As you see i just changed the type="text" for type="email" and then i can use in my view:

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

And the html source gives:

<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> 
待"谢繁草 2024-09-23 22:57:14

喜欢它能把这种类型的东西从模型上赶走!!我用 [DataType(DataType.PhoneNumber)] 装饰了我的模型,除了一个之外,所有模型都有效。

我意识到 @Html.TextBoxFor 不会渲染 type="" 而是 @Html.EditorFor做。我想现在考虑一下是有道理的,但发布此内容可能是为了让其他人节省我刚刚失去的令人沮丧的几分钟;)

Love it when can drive this type of stuff off the model!! I decorated my models with [DataType(DataType.PhoneNumber)], and all but one worked.

I realized the hard way that @Html.TextBoxFor doesn't render the type="<HTML5 type>" but @Html.EditorFor does. Makes sense I guess now that I think about it, but posting this to maybe save others the frustrating few minutes that I just lost;)

冰雪之触 2024-09-23 22:57:14

我发现自己想要使用 HtmlHelper 中的 时获得的数字旋转器,最终我自己解决了这个问题。

与上面 RPAlbert 的 Html.EmailFor 答案类似,我开始使用普通的 Html.TextBoxFor,但后来我使用 LinqToXml 来修改 HTML,而不仅仅是使用字符串替换。

从 Html.TextBoxFor 开始的优点是您可以使用 MVC 为您完成的所有客户端验证内容。在本例中,我使用 data-val-range 属性中的值来设置约束微调器所需的最小/最大属性。

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 属性中获取它们。

我希望这有帮助!

I found my self wanting the number spinner you get when using <input type='number' /> from an HtmlHelper, and ended up solving it my self.

In a similar fashion to RPAlbert's Html.EmailFor answer above, I started off using the normal Html.TextBoxFor, but then I used LinqToXml to modify the HTML rather than just using a string replace.

The advantage of starting with the Html.TextBoxFor is that you can use of all the client side validation stuff that MVC does for you. In this case I am using the values from the data-val-range attributes to set the min/max attributes needed to constrain the 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());
}

You would then use it as you would any other HtmlHelper in your views:

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

This was my implementation of it anyway, from you question I can see that you wanted:

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

It would be very simple to tweak my method to do this as follows:

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

Basically all I have done is to rename it and provide min/max as arguments rather than getting them from DataAnnotation attributes.

I hope that helps!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文