Skip to content


Subversion checkout URL

You can clone with
Download ZIP
That is a jquery plugin, which emulates HTML5 Form behavior on old browsers. The plugin also allows to customize form submission validation tooltips and field validation callbacks (e.g. via XMLHttpRequest)
JavaScript HTML CSS

HTML5 Form Shim


Build Status Bower version

That is a jQuery plugin, which brings HTML5 Form support on legacy browsers and allow to extend HTML5 Form on new ones. Different browsers provide different look&feel for the form elements. However you would hardly able to re-style bubble validation messages , date-picker, color-picker and others. With this plugin you may intercept browser native HTML5 Form API control and, therefore, have all the attached UI components always in the same style. Besides, you can have own validation messaging (e.g. showing messages next to the field instead using tooltips).

How to use

To enable the shim you simply mark forms with data-enable-shim="true" while running jQuery and this plugin.

    <script src="//"></script>
    <script src="./build/jquery.html5form.min.js" type="text/javascript"></script>
<form data-enable-shim="true">

You can also install the library by using Bower:

bower install html5formshim --save

See details on how to use HTML5 form at


Take in the account that legacy browsers ignore CSS pseudo-classes :focus, :invalid, :valid, so use instead classes focus, invalid, valid.

NOTE: The examples below use CSS3 styles. If you want your forms not only behave, but look the same in all browsers, use simple styles


  • The constraint validation API exposed on HTMLElement for legacy browser and on h5FormShim input wrappers (e.g. input.checkValidity(), input.validationMessage, input.validity.typeMismatch where var input = hfFormShim.getInput("#email")).
  • Can show validation messages on custom elements
  • Easy attach of 3rd-party-made widgets (datepicker, colorpicker, slider as so on)
  • Allows custom on-submit tooltips
  • Allows custom input type validators
  • Allows custom on-input callbacks
  • Shim formaction, formenctype, formmethod, and formtarget attributes
  • Covered with tests
  • Implemented as UMD (can be used as AMD or CommonJS modules)

Example 1: Custom form submission validation

<form class="example1" data-custom-validation="true" data-enable-shim="true">
    <label for="name">Name:</label>
    <input type="text" placeholder="Name" required="true" name="name"  />
    <label for="email">Email:</label>
    <input type="email" placeholder="Email" autofocus="true" required="true" name="email" />
    <label for="name">Age:</label>
    <input type="number" required="true" name="age" min="18" max="100" />
    <label for="email">Promo code:</label>
    <input type="text" name="promocode" required="true" pattern="[A-Z]{3}[0-9]{4}"
title="Promo code consist of 3 uppercase letters followed by 4 digits." />
    <label for="email">Tel:</label>
     <input type="tel" name="tel" required="true" pattern="^\+(?:[0-9] ?){6,14}[0-9]$"
title="Please enter valid tel." />
    <button type="submit">Submit</button>

This form shows custom tooltips as on old browsers as well as on those supporting HTML5.

To make the form showing your custom tooltip on submission validation, define data-custom-validation property on the form element.

The plugin will use $.setCustomValidityCallback to display validation messages. You can override this callback with your own function:

   $.setCustomInputTypeValidator = function( type, msg, validatorCb, initCb ) {
         Control[ type ] = function() {
                return {
                    "__extends__" : AbstractControl,
                    "__init__": function() {
                        initCb && initCb.apply( this.boundingBox, [ this ] );
                    validateValue: function() {
                        validatorCb.apply( this.boundingBox, [ this ] ) ||
                            this.throwValidationException( "customError", msg );
                        return this.logger;

Example 2: Showing validation messages on custom elements

<form class="example2" data-custom-validation="true" data-enable-shim="true">
    <label for="email">Email:</label>
    <input id="f2email" type="email" placeholder="Email" required="required" name="email" />
    <div class="help-inline">
        <div data-validation-message-for="f2email"></div>
    <label for="name">Age:</label>
    <input id="f2age" type="number" required="required" name="age" min="18" max="100" />
    <div class="help-inline">
        <div data-validation-message-for="f2age"></div>
    <button class="btn btn-inverse btn-large" type="submit">Submit</button>

This form is forced to custom validation by attribute data-custom-validation. So whatever browser you use it displays validation messages on the elements marked as data-validation-message-for="<input-id>"

Example 3: Custom input type validation

<form class="example3" data-enable-shim="true">
    <label for="name">Zipcode (custom input type):</label>
    <input type="zipcode" placeholder="Zipcode" required="required" name="zipcode"  />
    <button class="btn btn-inverse btn-large" type="submit">Submit</button>

You can easily define your own input validator by using $.setCustomInputTypeValidator. It receives following arguments:

type description
(string) Input type (here Zip for <input type="zip">)
(string) Input value validation message
(function) Validation callback (returns boolean)
(function) (OPTIONAL) Initialization callback
$.setCustomInputTypeValidator( "Zip", "Please enter a valid zip code", function() {
    var pattern = /^[0-9]{6,8}$/;
    return pattern.test( $( this ).val() );

Mark that the input element is available within the callback as the context (this).

Example 4: Attaching 3rd-party widgets to form elements

<form class="example4" data-enable-shim="true">

    <label for="color">Color:</label>
    <input type="color" name="color" value="#d4251b" />

    <label for="date">Date:</label>
    <input type="date" name="date" />

    <button class="btn btn-inverse btn-large" type="submit">Submit</button>

You can attach to any input element a custom handler. Thus you can enrich inputs of such types as color, date, datetime, week, moth, time, range with corresponding widgets (e.g. how it's implemented in latest Chrome/Opera releases).

In the example below you can find color input using colorPicker jQuery-plugin and date input using jQueryUI datePicker

// Custom color input handler example
$.setCustomInputTypeValidator( "Color", "Please enter a valid hex color", function() {
        var pattern = /^#(?:[0-9a-f]{3}){1,2}$/i;
        return pattern.test( $( this ).val() );
}, function( control ) {
        control.isShimRequired() &&
                onChange: function( hsb, hex, rgb ) {
                        control.boundingBox.val( "#" + hex );
                onBeforeShow: function () {
                        $( this ).ColorPickerSetColor( this.value );

// Custom date input handler example
$.setCustomInputTypeValidator( "Date", "Please enter a valid date", function() {
        var pattern = /^\d{2,4}(-|\/)\d{2,4}(-|\/)\d{2,4}$/i;
        return !$( this ).val() || pattern.test( $( this ).val() );
}, function( control ) {
        control.isShimRequired() &&

As you see here last argument of $.setCustomInputTypeValidator is initialization callback. It injects dependency to input control handler (control). From which you can access the element control.boundingBox ( the same as $(this) ) and methods such as control.isShimRequired() (indicates if if the input type supported)

Example 5: Custom oninput callback

<form class="example5"  data-custom-validation="true" data-enable-shim="true">
    <label for="email">Email:</label>
    <input type="email" placeholder="Email" required="required" name="email" />
    <label for="password">Password:</label>
    <input type="password" required="required" name="password" />
    <label for="confirm">Password confirmation:</label>
    <input type="password" required="required" name="confirm" />
    <button class="btn btn-inverse btn-large" type="submit">Submit</button>

HTML5 introduces a new event input, which can be handled to perform additional validation tests on a field. For example, making registration form you can define a handler which checks by XMLHttpRequest if the given email already exists in DB. Here an example for a cross-browser on-input handler:

$('form.example3 input[name=confirm]').on("input", function () {
    var input = $(this);
    if (input.val() != $('form.example3 input[name=password]').val()) {
    input.setCustomValidity('The two passwords must match.');
    } else {
    // input is valid -- reset the error message



.init( options ):

Repeat initialization on a given form or all the forms in DOM if no argument given

Whereas options is an object of the following structure:

    boundingBox: formNode, // OPTIONAL
    inputs: "input, textarea, select", // OPTIONAL, by default "input, textarea"
    handlers: { // OPTIONAL
        onSubmit: fn()

If boundingBox property is missing, all the form marked with data-enable-shim="true" will be initialized. It's pretty handy for ebling HTML5FormShim on dynamically built pages

.getInput( $input ): AbstractInput

Obtain AbstractInput (hfFormShim input wrapper) for the given node to get access to The constraint validation API

.onReady( callback ): self

Invokes the callback function when all the specified forms initialized. The callback takes one parameter - page object. You can obtain one of initialized form objects by index page.getForm( index ).


.validator.reset(): void

Reset input validation state to defaults

.validator.checkValidity(): boolean

Run all the validity tests (validateRequired, validateValue, validateByPattern, validateCustomValidity) and return validation status

.validator.validateRequired(): boolean

Throws validation exception if input value is empty on a required input

.validator.validateCustomValidity(): void

Throws validation exception if input node data-customvalidity attribute has been modified. Handy when data-customvalidity been changed externally (e.g. AJAX)

.validator.validateByPattern(): void

Throws validation exception if input value doesn't match the provided pattern

.validator.validateValue()(): void

Throws validation exception if constraints given to this input type are not satisfied

.throwValidationException( validationProperty, validationMessage )

Trigger validation exception which reflects on The constraint validation API

.shim.isShimRequired(): boolean

Shim is required when the input type isn't supported or custom validation requested (data-custom-validation="true")

.shim.degrade(): void

Set attribute to text to avoid collisions with browser embedded input handlers

Class Digram

Class Diagram


The project can be built with Grunt task runner. During the build Grunt validates the JavaScript sources with jshint and jscs, compiles JavaScripts UMD modules using cjsc, runs Qunit tests and minifies JavaScript. To make a build just fire up Grunt anywhere within your project directory:

Producing .build/jquery.html5form.min.js

grunt build

Producing .build/jquery.html5form.js

grunt debug

Running automated tests and code style validation

grunt test

As you commit TravisCI reports you if the build isn't successful


Something went wrong with that request. Please try again.