Use HTML5 form attributes now with nmcFormHelper plugin for jQuery

December 7, 2009

Inayaili de León's post last week on 24 ways reminded me about some of the new attributes that HTML5 will be adding to the <input> element. In addition to the flashy new input types (search, color, date, etc.), there are several more mundane, but just as useful, new attributes that can be used on the input types we already have. I created a small jQuery plugin that checks if these attributes are supported natively, and if not it adds support via JavaScript. See an example, or continue reading for the full explanation.


A common trick is to set the value of a text input to a short hint about the type of information that should be entered there. Then a couple lines of JavaScript are used to clear that value when the user clicks or tabs into the input. Although there are usability issues with this technique, its convenience is hard to resist. The HTML5 spec includes a new placeholder attribute that creates the same effect without the usability problems.

To Use:

<input type="text" name="name" id="name" placeholder="Enter your first and last names" />


When the primary purpose of a page is the form—a login page, for instance—it is helpful to start out with the focus on the first input, so the user can just start typing. You can use the new autofocus attribute on the first element to do that. (Be careful, though: setting autofocus on a non-essential form, like a comment form, can be very annoying.)

To Use:

<input type="text" name="name" id="name" autofocus="autofocus" />


Setting the required attribute prevents the form from submitting unless the input has some value.

To Use:

<input type="text" name="name" id="name" required="required" title="This is required" />


The pattern attribute lets you set a regular expression pattern that must be matched by the input value before the form can be submitted. This is a very powerful tool, allowing for complex validations. Our HiFi RexExp Tool will help you create regular expressions that test for anything from credit card numbers to urls. You should also read the HTML5 spec on the topic, as there are a few caveats. In particular, be aware that the pattern matches the entire value by default, and you should not wrap the expression in forward slashes.

To Use:

<!-- Only accept US zip codes -->
<input type="text" name="zip" id="zip" pattern="(^d{5}$)|(^d{5}-d{4}$)" title="US zip codes only" />

Using the Plugin

Some or all of these new attributes are supported by both Safari and Opera. But Firefox and Internet Explorer do not support them natively at this time. To be safe, the nmcFormHelper plugin checks for availability of each attribute (using a technique suggested by Mark Pilgrim) and, if it doesn't exist, uses JavaScript to emulate support.

At a minumum, you just need to include my script and place a single line in your $(document).ready() block: nmcFormHelper.init();. That will set up all of the new attributes, and you're ready to go.


  • Placeholder styling: The placeholders are styled to match the native placeholder functionality in Safari. If you wish to set a different style, you can set nmcFormHelper.placeholder.styling = {'color':'red','font-style':'italic'}; or whatever look you choose.
  • Validation functions: The required and pattern attributes will prevent form submission and display an error if the value does not exist or does not match the pattern. By default, a new label will be added after each invalid input, containing the title text of the input. But you can write a function to do anything you want! Just override the functions nmcFormHelper.validation.showErrors and nmcFormHelper.validation.hideErrors (the latter function should undo the former). Both functions will be passed a jQuery object containing all the elements that are affected. Each element will also have one or both of the classes "requiredError" or "patternError" set.


Since Internet Explorer does not support CSS attribute selectors, it can be hard to style a text input, for instance, without screwing up your buttons, or vice-versa. So the plugin also adds a class to each of your inputs containing "input-" and the type of the input (i.e. "input-submit"). That way, you can style them individually.

See an example

Get the Code

Full, commented version

Minified version


sanji's avatar
There is a difference in showing errors in IE. Can u check it?
@renato_cron's avatar
Well, i "Fix" editing the code and calling validation init ever, even when browser "support", because i'm using just class.
renato cron's avatar
renato cron
It's broken on Chrome 9.0 ! OMG!

i'll try to fix
Stephan Sokolow's avatar
Stephan Sokolow

Glad to hear it on both counts.

Just a reminder to Eli: Don't forget to also declare the license in the JS file itself. I always find it a big pain when I find a file in some project somewhere with different licensing terms and the only remaining mention of the license has to be manually looked up on a page which sometimes only exists in the wayback machine.

Joel's avatar
Joel NMC team member


Eli is out of the office this week, but I am sure he intended the plugin to be MIT licensed. He'll update the post accordingly when he gets back.

The apostrophe bug is happening on webkit and is not something we want to happen. I finally got around to tracking it down and it turned out to be caused by jQuery scrollable. I updated to a newer version and apostrophe issue seems to be resolved.

Stephan Sokolow's avatar
Stephan Sokolow

What are the licensing terms for nmcFormHelper? I can't find any mention of them and, in my experience, that means that use of the plugin is legally iffy. (My guess is that you intended either a MIT/newBSD or WTFPL-style license, but I can't be sure)

...oh, and I'm also worried about the trustworthiness of your code now. I had to copy-paste apostrophes because you've apparently got some Javascript which blocks them from being typed and I'm not currently on a browser with NoScript. (It has the feel of a "worse than nothing" attempt at preventing SQL injection)

Eli Van Zoeren's avatar
Eli Van Zoeren

Good catch. The newest version of this script replaces password fields with regular text fields until they receive focus, which they get switched back to password fields. Its a rather complicated operation, so let me know if you find any bugs.

I suppose it might be strange to use the title field for that, but I wanted to avoid hardcoding error messages into the script. I will revisit this at some the mean time it should be easy to modify to get the messages from wherever you want.

Your second point is now fixed.

John Doe's avatar
John Doe

Thanks for the script, just a couple of things:
- It seems strange to use the title of a field to contain an error message, even before there is an error, I wouldnt call this semantically correct
- It is allowed to use inputs without a type attribute, these are text inputs. This leads your script to create class="input-undefined", perhaps you could tweak the script so that undefined defaults to text.

Laz's avatar

Great script, thanks!

I was wondering... for "password" inputs it does show me ******* instead of "password", of course. Any way to work around that?


Eli Van Zoeren's avatar
Eli Van Zoeren

Both of the suggestions Chris made have been incorporated into the newest version of this plugin. Keep them coming!

Chris's avatar

For anyone who wants to add #2 themselves, the code is:

$(window).bind('unload', function() {

Chris's avatar

Great plugin. I have two thoughts:

1. I would swap the $input.val(... and $input.css(... lines in the method. When I tested it I noticed the text show up in black first, and then change to gray (in Firefox 3.5). If you set the CSS and then set the value, it will show immediately as gray.

2. Firefox remembers the last value of a form element on the page and sets that element's value attribute on refresh. That means that if you refresh a page with this script enabled, all elements will have the placeholder text as their value. It might be worthwhile to add a onbeforeunload event listener that calls nmcFormHelper.placeholder.hide() on all matched elements.



Leave a comment