Earlier this week, I wrapped up the third installment of my “Building Apps for HTML5” Series for MSDN Magazine (check out part 1 and part 2, if you haven’t already), and there was an out of scope item that I didn’t have the space to cover, but thought would be a good blog post.

The article was about HTML5 Web Forms, essentially the new input types (email, tel, number, date, etc.), new attributes (autofocus, placeholder, etc.) and new form validation goodies (required, pattern, formnovalidate, etc.). It was a fun article to write, and it’s slated to drop in early November.

One of the questions that often comes up from .NET developers when I talk about HTML5 Web Forms is how these features integrate with ASP.NET Web Forms or MVC. In the article, I speak briefly about updates like VS 2010 SP1 and the mouthfully-named “Reliability Update 1 for .NET Framework 4,” and Scott Hunter has a nice, succinct blog post that covers both, and which you can check out here.

What I wasn’t able to cover in the article, though, was some specifics around using these new input types and attributes with ASP.NET MVC, specifically how one would use these with Strongly-typed HTML helpers in MVC. That’s the purpose of this post.

But first, since the article isn’t out yet as I’m writing this, a quick primer on HTML5 Web Forms for those not familiar.

What’s HTML5 Web Forms?

HTML5 Web Forms (one of the earliest pieces of what we now call “HTML5”) lives in the official W3C HTML5 Specification, which you can read yourself at http://www.w3.org/TR/html5/forms.html. A significant portion of the specification is dedicated to new types and content attributes for the input element, which can be found here: http://www.w3.org/TR/html5/the-input-element.html. For a more digestible resource on HTML5 Forms, I recommend the excellent Forms chapter (“A Form of Madness”) from Mark Pilgrim’s HTML5: Up and Running.

The specification introduces 13 new input types (<input type=”?” />) for use in our forms. Here’s the list:

  • search
  • email
  • tel
  • url
  • datetime
  • date
  • month

     

  • week
  • time
  • datetime-local
  • number
  • range
  • color

     

Each of these new types comes with some interesting behaviors and features. Each also has varying levels of support in the major browsers, but since I cover that in depth in my article (and others have online), I’m not going to rehash it here. For the purposes of this post, let’s assume that I’ve decided to use these new features, am using feature detection (either rolling my own or via Modernizr) and have chosen a polyfilling library or two to fill the gaps in functionality back to older browsers. Of course, I probably should point out that there’s no reason NOT to use any of these new types today. If an older browser encounters a type it doesn’t recognize, it will just change the type attribute to “text,” which is what you’re already using. But newer browsers get all of the built-in validation and presentation provided by the browser.

Using HTML5 Web Forms

All you need to do to get started with HTML5 Forms is use any of the new input types or attributes on a form. Let’s take a look at the markup (snipped a bit) for a sample form (coincidentally, the same form from my article)

Note: If you cannot view the embedded Gist above for any reason, click here to view the embedded code.

Here’s the resulting form:

image

You probably noticed a few new things in the markup above, and I’ll summarize them briefly here (again, without detracting too much from the point of this post):

  1. New type=”” values on inputs (email, url, tel, date and number) – All of these do exactly what you’d expect them to.
  2. A “required” attribute – Tells the browser that this field must have a value before the form can submitted
  3. An “autofocus” attribute – Notifies the browser that a given field should automatically receive focus (a cursor) when the page loads
  4. A “placeholder” attribute – Instructs the browser to overlay hint text when the field is empty. The first three fields above us this, as you can see from the screenshot.
  5. A “pattern” attribute – Provides a regular expression for the browser to use when validating the form. Above, I’m telling the browser that I’ll only accept telephone numbers in “(xxx) xxx-xxxx” format.
  6. “min” and “max” attributes – For type=”number” the minimum and maximum allowed values for the field to be valid.
  7. “A “formnovalidate” attribute – Tells the browser to turn off validation for a submit field. In this case, I use the “Save for later” button to allow the user to save an order in process and return to it later.

In addition to what I’ve listed above, a few of these fields provide some automatic validation when I invoke their type. The email field must contain a valid email, url a valid URL, etc.

Enter ASP.NET MVC, Stage Right

As great as these new features are, if you’re using ASP.NET MVC, you’re probably asking yourself a couple of questions right now.

1) How do I use this with strongly-typed HTML helpers?

2) How do I use this with existing DataAnnotations on my model?

Let’s take a look at each of those in turn.

HTML5 Forms and HTML Helpers

If you’re a fan of the HTML helpers in ASP.NET MVC, you probably don’t type this very often

<input type=”text” id=”orderName” />

And instead prefer something more like this:

@Html.TextBoxFor(m => m.Name)

Or even just Html.TextBox.


In the case of our first element, the Name field, using this with the new HTML5 attributes is easy:



 

@Html.TextBoxFor(m => m.Name, new { required = "required",
                      autofocus = "autofocus",
                      placeholder = "ex. Huggie Reyes" })

This will emit effectively the same markup as the original, raw field. So the good news is that, as you would expect, the new attributes work just fine with the HTML Helpers.

The real problem is with the rest of my fields, all of which use type values not yet fully supported by the HTML helpers (i.e. type=”email”). For these, I can use the @type property in the anonymous properties object, like so:

@Html.TextBoxFor(m => m.Email, new { @type = "email" , required = "required",
                      autofocus = "autofocus",
                      placeholder = "ex. hugo@dharma.com" })

There’s also no reason why you can’t just author markup by hand and keep the input values in sync with your model. But if you’re a attached to the helpers, or if you prefer the type be tied more closely to the helper call itself, the good news is that you have options.

HTML5 Forms and MvcContrib.FluentHtml

The best option, IMO, would be to check out MvcContrib, specifically the FluentHtml features from Tim Scott. FluentHtml has been around for a while, but Tim recently added support for many of the new HTML5 input types and attributes. It’s not yet in an official release, but you can build from the source, grab the MvcContrib.FluentHtml assembly, and follow the setup instructions here. Once we’re all setup,  we can take the raw markup from my order form above and use Fluent Html to yield the following:

Note: If you cannot view the embedded Gist above for any reason, click here to view the embedded code.

(While writing this post, I went ahead and implemented the FormNoValidate method on the SubmitButton type, so go grab the latest source for MvcContrib if you’re not up to date.)

Now, when you run the page again, you’ll see that functionally, everything still works as it did before, but you have the benefit of those strongly-typed helpers (and the elegance of the FluentHtml library, if you don’t mind my saying so.)

That’s Nice, But What About My Model Metadata?

In spite of all of this Fluent-y, typed goodness, I’m betting many of you are still bothered by one aspect of using the new input types and attributes on your forms, especially if you’re a fan of annotating your Models with validation attributes (DataAnnotations) like [Required], [Range] and [RegularExpression]. Chances are, when you saw the example markup above with required and pattern attributes, you thought to yourself “Awesome, so how can I use my existing DataAnnotations with these new attributes?”

If you asked that question, You’re probably using MVC Client Validation (introduced in MVC 2) or Unobtrusive Client Validation (introduced in MVC 3), whereby the Model metadata you implement on a given model is used by the framework to generate client validation scripts or data- attributes for use by the client validation framework. These are both fantastic approaches for keeping your validation DRY and consistent from the client to the server, and you should keep using them.

But the reason why HTML5 Forms Validation is so compelling is because it moves client validation squarely into the browser’s lap, meaning that no client-side JavaScript is needed to perform validation before a form is submitted to the server. Of course, script-based client validation should continue to be your first fallback option—with server validation as the last checkpoint—but leveraging in-browser validation for the growing number of users with a modern browser means increased performance and a better user experience.

“That’s great,” you say, “but what about those DataAnnotations?”

With the help of MvcContrib.FluentHtml and a couple of custom behaviors, we can quickly introduce a mechanism that will leverage our model metadata for validation, meaning that we can remove all instances of Pattern(), Required() and Limit() from our example fluent markup above, and the proper HTML attributes will be added on our behalf. Let’s assume that this is my model:

Note: If you cannot view the embedded Gist above for any reason, click here to view the embedded code.

And, rather than manually specifying required, pattern and min/max on my markup (which would be repetitive), I want to have those attributes added for me when the appropriate Model attributes are present. MvcContrib.FluentHtml introduces a mechanism whereby I can define a series of behaviors that I want to apply to a single element, or an entire page. I start by implementing the IBehavior<IMemberElement> interface. Here’s an example where I’ve created a RegularExpressionBehavior:

Note: If you cannot view the embedded Gist above for any reason, click here to view the embedded code.

Once I’ve created all of the behaviors I need (in this example, I need custom behaviors to fetch Required, RegularExpression and Range attributes), I’ll then create a ViewPage that inherits from ModelViewPage<T> (a type provided by MvcContrib.FluentHtml that I need to use the fluent helpers) and provides the base class with instances of my custom behaviors. Here’s the one I’ve created:

Note: If you cannot view the embedded Gist above for any reason, click here to view the embedded code.

Now, all that’s left for me to do is to inherit my ViewPage from the custom ViewPage, and remove the Required(), Pattern() and Limt() calls from my page. For Razor, just add the following to the top of your ViewPage

 

@inherits FluentHmlt5ViewPage<Order>

Where “Order” is your Model or ViewModel. Obviously, you’ll need to tweak this if you’re using a different view engine.

After removing the statements we don’t need to specify on the view, our markup looks much cleaner, and it’s using Model metadata to set validation attributes for the browser!

Note: If you cannot view the embedded Gist above for any reason, click here to view the embedded code.

So there you have it, HTML5 Forms, ASP.NET MVC and Model validation all living in harmony together!

If you’re interested in trying out FluentHtml with HTML5 Forms and the custom behaviors I describe here, I’ve added a basic solution with the 3 custom behaviors and a custom ViewPage object to GitHub as FluentHTML5. Feel free to download it here, and let me know what you think. If its useful, I might expand this with other behaviors.

Tagged with:
 
  • http://www.scoop.it/t/silverlight/p/485761133/html5-forms-with-asp-net-mvc-and-mvccontrib-fluenthtml HTML5 Forms with ASP.NET MVC and MvcContrib.FluentHtml | Silverlight | Scoop.it

    [...] HTML5 Forms with ASP.NET MVC and MvcContrib.FluentHtml Earlier this week, I wrapped up the third installment of my “Building Apps for HTML5” Series for MSDN Magazine (check out part 1 and part 2, if you haven’t already), and there was an out of scope item that I didn’t have the space to cover, but… Source: userinexperience.com [...]

  • Jason

    Looks neat, thanks! 

  • Greg Hayden

    Und so I downloaded the project and the required MvcContrib.FluentHtml.dll from Ceodplex; however, the compiler complains (and the object browser confirms) that dll has no definitions for ‘Max’, Min’, ‘Pattern’, or ‘Required’. Is there a newer version of the dll or did I miss a step?

  • http://www.deadlywind.com/ Paintball Barrel

    my head, my head….

  • Vince Panuccio

    The problem with having the browser do all the validation is the way it styles the validation messages and input controls. Documentation is next to impossible to find, and the docs I have found, are inconsistent between browser versions.

    For this reason I’ll be using JS validation for some time to come.

    That being said, I still output HTML5 attributes you mentioned above so the markup has the correct semantics and meaning.

    Has anyone found docs on styling validation messages and also changing those messages?

  • http://teelahti.myopenid.com/ TT

    I think you have some misinformation in your post: you can use type attributes with built in HTML helpers. This works just fine and outputs input type=email:

    @Html.TextBoxFor(m => m.Email, new { @type = “email” })

  • http://teelahti.myopenid.com/ TT

    I think you have some misinformation in your post: you can use type attributes with built in HTML helpers. This works just fine and outputs input type=email:

    @Html.TextBoxFor(m => m.Email, new { @type = “email” })

  • http://www.alvinashcraft.com/2011/10/11/dew-drop-october-11-2011/ Dew Drop – October 11, 2011 | Alvin Ashcraft's Morning Dew

    [...] HTML5 Forms with ASP.NET MVC and MvcContrib.FluentHtml (Brandon Satrom) [...]

  • http://www.biggestguru.com/category/blogs/top-3-stories-from-msdn-flash-oct-11 Top 3 Stories from MSDN Flash Oct 11 | BIGGEST GURU

    [...] HTML5 Forms with ASP.NET MVC and MvcContrib.FluentHtml [...]

  • http://www.userinexperience.com Brandon Satrom

    Thanks TT, you are correct, and I failed to mention that option. I’ve just updated the post to include that piece of information as well.

  • http://www.userinexperience.com Brandon Satrom

    Hi Greg,

    These new aspects of FluentHtml aren’t yet in an official release, so you’ll need to grab the source and build the project yourself.

  • http://www.userinexperience.com Brandon Satrom

    Hi Vince,

    That’s a perfectly reasonable approach. I agree that the current state of Forms and Validation does leave something to be desired. The good news is that we are moving in the right direction, and I would expect to see not only more consistent implementations across browsers, but also full control over the styling of form elements and validation. In the meantime, using the attributes for semantic purposes is great.

  • http://sandervandevelde.wordpress.com/2011/10/11/vereenvoudig-toch-die-input-in-html4/ Vereenvoudig toch die input in HTML4 | Sander van de Velde

    [...] hierboven te zien, zijn er al een aantal browsers druk bezig met die integratie. De laatste tijd wordt ook druk gewezen dat het al toegepast kan gaan worden bij de bouw van websites. Dit is leuk voor de gebruiker van [...]

  • http://www.biztalkguy.net/post/2011/10/12/HTML5-with-ASPNET-MVC.aspx Biztalk Musings | HTML5 with ASP.NET MVC

    [...] with ASP.NET MVC October 12, 2011 17:59 by btsguy http://userinexperience.com/?p=692 09e562d4-9189-4ae3-b542-7dc938c721b3|0|.0 Tags: mvc, asp.net, html5 Categories: ASP.NET | MVC [...]

  • Felix Rabinovich

    Wiat… How did you force FluentHTML to generate EmailBox and UrlBox instead of TextBoxFor?

    Ideally, I would want to mark elements in my model, say [DataType(DataType.EmailAddress)] and have the libraries generate EmailBox for HTML5 with fallback for Javascript validation.

    If I have to write EmailBehavior() I’d rather write it once and compile it into the library (or as some extension if I don’t have the code).

  • http://msprogrammer.serviciipeweb.ro/2011/10/21/friday-links-3/ friday links « A Programmer with Microsoft tools

    [...] HTML5 Forms with ASP.NET MVC and MvcContrib.FluentHtml | User InExperience [...]

  • http://msprogrammer.serviciipeweb.ro/2011/12/16/friday-links-11/ friday links 11 « A Programmer with Microsoft tools

    [...] HTML5 Forms with ASP.NET MVC and MvcContrib.FluentHtml | User InExperience [...]

  • http://www.coolspirit.org/blog/?p=22 HTML5表单与ASP.NET – CoolSpirit

    [...] 《HTML5 Forms with ASP.NET MVC and MvcContrib.FluentHtml》 [...]

Switch to our mobile site