HTML5 is currently at the W3C candidate recommendation stage, but the release of a stable HTML5 Recommendation is still at least a year out. As such, cross-browser support for HTML5 remains subpar. If you want to utilize some of the newer HTML5 features, using a polyfill can help.

In my case, I had a need to use HTML5 client-side form validations and the HTML5 date-helper form input recently. I researched Webshims, a JS polyfill, and found it to be well maintained: It has good documentation, it's frequently contributed to on Github, and it loads only needed features, thus avoiding any significant performance hits.

In Rails 4, using Webshims can be slightly confusing. It's not sufficient to plop it into your asset pipeline and then have it precompiled as it's pushed to production. If you do this, it will result in 404 errors due to missing assets. This is because Webshims does not support the fingerprinting of assets, and Rails 4 did away with including non-digest filenames in the public/assets/ directory. Static files such as Webshims should therefore live under the public/ directory. Here are my thoughts on the optimal way to achieve this:

First, we'll have to do some shimmying. Click the download link on the documentation site . Then, go and find webshims-stable in your downloads folder, and optionally rename it's subdirectory from js-webshim to webshims. Next, navigate into the minified subdirectory, and move the 'extras' and 'shims' folders, as well as the 'polyfiller.js' file, up a directory. Proceed to delete the 'dev' and 'minified' folders. Then, copy the webshims folder and paste it into vendor/assets/javascripts in your rails app.

Under vendor/assets/javascripts/, create a new file called webshims.js. Have it look like this:

$.webshims.polyfill();

This line initializes webshims with all of its features. You can optionally pass arguments declaring which polyfills you want loaded, as below:

$.webshims.polyfill('forms forms-ext');

This loads both the forms and forms-ext polyfills, options for which can be seen here .

You should now be able to use HTML5 features and have them be supported in any of the modern browsers, at least in your local development environment. If your working to get HTML5 client-side validations integrated into your app, the following is handy:

$.webshims.setOptions('forms', {
    customMessages: true,
    replaceValidationUI: true
});

// Improve custom messages
$.webshims.validityMessages['en'] = {
    typeMismatch: {
        email: 'Please provide a valid email.',
        url: 'changed {%value} is not a valid web address',
        number: 'changed {%value} is not a number!',
        date: 'changed {%value} is not a date',
        time: 'changed {%value} is not a time',
        range: 'changed {%value} is not a number!',
        "datetime-local": 'changed {%value} is not a correct date-time format.'
    },
    rangeUnderflow: '{%value} is too low. The lowest value you can use is {%min}.',
    rangeOverflow: 'changed {%value} is too high. The highest value you can use is {%max}.',
    stepMismatch: 'changed The value {%value} is not allowed for this form. Only certain values are allowed for this field. {%title}',
    tooLong: 'changed The entered text is too large! You used {%valueLen} letters and the limit is {%maxlength}.',
    patternMismatch: 'changed {%value} is not in the format this page requires! {%title}',
    valueMissing: 'Please fill out this field.'
};

The setOptions property allows you to configure the options for a specific feature, such as 'forms' above. The customMessages option, which is self-explanatory, allows you to set custom messages for your validations (if it is set to true). You can then declare your custom messages using the $.webshims.validityMessages property. I've customized the email and valueMissing fields above, but you can configure it as much as you'd like.

With that in place, HTML5 client-side validations are as simple as setting the required attribute to true on your form inputs. This will result in little popups appearing below invalid input fields when the user clicks to submit the form, like so:

webshims popup

Here's a code example using a Rails form helper with the HTML5 required attribute. This is used on the landing page of Strengthify to validate emails:

<%= f.email_field :recipient_email, required: true, placeholder: "No spam. Pinky promise" %>

Since we've specified an e-mail field here, and not just a text field, HTML5's built-in validators will not only check that the field is filled in, but will also check for the validity of the e-mail as well.

If you want the user to have more immediate feedback on whether the fields being filled in will pass your validations, you can set the class "ws-instantvalidation" on the form tag:

<%= form_for(YOUR_OBJECT_HERE, :html => {class: "ws-instantvalidation"}) do |f| %>

Here's a 12-second video clip of how instant validation looks with the previously mentioned e-mail field. If you want to customize the styles for the validation messages, all you have to do is hook into the .ws-errorbox class (which wraps the message) in your CSS.

Using webshims to polyfill unsupported HTML5 widgets like the date helper is even easier. Simply specify that your using an HTML5 date_field and webshims will go ahead and polyfill it for you if there is no native browser support for it.

Conclusion

Webshims is an easy way to improve validation feedback and improve user experience for processes requiring user input. HTML5 is still not widely supported (e.g. Safari), so using a polyfill can be a good idea.

Comments? Discuss on Hacker News