Webshims Lib

Polyfill only the incapable browsers

Documentation adding/changing/styling validation messages with webshims constraint validation

Overriding native validation messages/native validation UI

With HTML5 there are two possible ways to change the validation messages.

  • Preventing the native invalid message to appear and replacing it with your own invalid UI (including own validation message or native validation message)
  • changing the messages through the setCustomValidity-method - without changing the native UI

A starting point for Preventing the default invalid UI and then replacing it, could look like this:

$('form').bind('invalid', function(e){ //prevent browser from showing native validation message e.preventDefault(); //implement custom UI and custom message according to the validityState $(e.target).attr('validity') });

Note: The HTML5 invalid event does not bubble. Webshims lib uses event capturing for listening to the invalid event, so that it can be captured on the form/all ancestor elements

Webshims lib gives you some extensions to make styling validation error message or changing the error-messages really simple.

  • firstinvalid (event)
  • customValidationMessage (DOM-Property) (Note: to get this new property either customMessages or overrideValidationMessage has to be set to true before calling $.webshims.polyfill();)
  • $.webshims.validityAlert (Helper Object)
  • data-errormessage/-x-moz-errormessage content attributes (are automatically used by validityAlert)

Preventing the default and replacing the invalid-bubble with your own message, could look like this:

$('form') .bind('firstinvalid', function(e){ //show the invalid alert for first invalid element and pass the custom validation message $.webshims.validityAlert.showFor( e.target, $(e.target).prop('customValidationMessage') ); //prevent browser from showing native validation message return false; }) ;

Using $.webshims.validityAlert.showFor will generate the following styleable HTML structure:

<!-- note: span.validity-alert-wrapper is label.validity-alert in old browser, which do not support WAI-ARIA --> <span class="validity-alert-wrapper" role="alert"> <span class="validity-alert"> <span class="va-arrow"><span class="va-arrow-box"></span></span> <span class="va-box">Error message of the current field</span> </span> </span>

Firefox 4.0 also shows an invalid hint on mouseover, which can't be replaced by this technique. If you want to remove this you can use a title-attribute with an emtpy string or use the x-moz-errormessage to control the error message.

Using instead the setCustomValidity approach will fully replace the validation message, while the native validation UI stays. Changing the validation message with setCustomValidity, would look like this:

$('input[required]').setCustomValidity('You have to enter something');

The problem with setCustomValidity is, that setCustomValidity is a low level API for changing the validityState of an element. This means: The changed validation message is only a side effect, setCustomValidity only works on a single element and also sets the customError-flag to true. The developer has to observe the validityState of an element and has to remove/change the custom validation message dynamically as soon as the message isn't relevant anymore, which can be a real pain in the ass.

//remove customError flag: $('input[required]').setCustomValidity('');

Due to the fact, that Webshims Lib already had to implement the setCustomValidity approach to do a lot of bugfixing in capable browsers/implementing in uncapable/semi-capable browsers, webshims lib gives you a simple configuration property to dynamically overriding the validationMessage with the customValidationMessage. Simply set the overrideMessages to true, before calling polyfill.

//configure custom validation messages before you call polyfill $.webshims.setOptions('forms', { overrideMessages: true }); $.webshims.polyfill();

Note: This site is loaded with overrideMessages = true;.

Recommendation: Prefer customMessages = true to overrideMessages = true (less obtrusiv)

Or a simple rule: If you want to style the validation tooltip use customMessages and if you want to only change the validationMessage without changing the validation UI use overrideMessages.

Changing and Adding validation messages

Webshims Lib validation messages are stored @ $.webshims.validityMessages as an object. The index is the specific language code. Currently there are only really bad validation messages for "en" and "de".

Webshims Lib automatically shows the validation message in the detected language of the browser. If the script doesn't find the right language, it will show the default language which is stored under the key "" (defaults to "en").

You can easily add/change a language by specifying a certain language code.

$.webshims.validityMessages['en'] = { typeMismatch: { email: 'changed {%value} is not a legal email address', 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: 'changed {%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: 'changed You have to specify a value' };

There are several placeholders, which you can use in your validation message: {%label} (the text of the label[for]), {%value}, {%title}, {%min}, {%max}, {%maxlength}, and {%valueLen}

It is also possible to add more fine grained messages by providing an error message for a specific type.

The following code changes the validation message for a rangeUnderflow in case of the date-type. But will show the defaultMessage in any other type.

$.webshims.validityMessages['en'] = { //... rangeUnderflow = { date: '{%value} is too early for {%label}. The earliest date you can use is {%min}.', defaultMessage: '{%value} is too low. The lowest value you can use is {%min}.' } //... }; $.webshims.validityMessages['en'] = { //... valueMissing = { radio: 'Please check one of these options', defaultMessage: 'You have to specify a value' } //... };

Please let me know, if you enhance the current messages or add new languages.

Create custom error bubbles in all browsers

The following code will explain how to create customized error hints in all browsers. Although it uses some webshims extensions, it shows how you can easily achieve this with HTML5.

//change language in all browsers to en (default is browser language) //$.webshims.activeLang('en'); //implement customValidationMessage //$.webshims.setOptions('forms', { // customMessages: true //}); //improve custom messages //$.webshims.validityMessages['en'] = { // //... // valueMissing = { // radio: 'Please check one of these options', // defaultMessage: 'You have to specify a value' // } // //... //}; //load features //$.webshims.polyfill(); //wait for DOM-ready and features $(function(){ $('form') //the invalid-event is the standard HTML5 validation event, //which is called on every invalid event, if the user trys to submit an invalid form or //the author calls checkValidity on an invalid element .bind('invalid', function(e){ //preventing the default means to cancel the UI-Behavior generated by the browser (so that we can replace it) e.preventDefault(); }) //custom event, which is fired on the first invalid element //preventing firstinvalid will prevent all invalid events (but we have already done this) .bind('firstinvalid', function(e){ //$.webshims.validityAlert is a usefull extension by webshim, which shows an error bubble at a certain element //simply call $.webshims.validityAlert.showFor(DOM-Element/jQuery-Object/jQuery-Selector); $.webshims.validityAlert.showFor(e.target, $.attr(e.target, 'customValidationMessage')); }) ; }); /*load russian localization*/ $.webshims.activeLang("ru"); /*load german localization*/ $.webshims.activeLang("de"); /*load english localization*/ $.webshims.activeLang("en");

Overriding global validation messages on a specific element

You can also set the attribute 'x-moz-errormessage' or 'data-errormessage' to override the global messages.

<label for="name">Name:</label> <input id="name" required data-errormessage="Please tell us your Name" />

Simple Demo

* Required fields

(min="2010-12-10" max="2016-01-01")
(min="3")

Radio-Group Headline Short Labels *

Legend Short Labels *

Now add some extras:

Add valid/invalid Classes on focusout.

//on focusout / blur $('form').bind('focusout invalid', function(e){ // get target element var $elem = $(e.target); //if the element is a candidate for constraint if($elem.attr('willValidate') && $elem.attr('type') !== 'submit'){ //test wether it is valid and set/remove the classes if(e.type !== 'invalid' && $elem.is(':valid-element')){ $elem .closest('.form-element, fieldset') .addClass('valid') .removeClass('invalid') ; } else { $elem .closest('.form-element, fieldset') .addClass('invalid') .removeClass('valid') ; } } });