Form validationStatusrelease
Check the information the user gives you to make sure it's valid
Guidance
Use this pattern to verify information provided by the user is suitable.
For more information on different types of validator, writing cutom validators, error messages and more see the validation library documentation.
Example
Dependencies and installation
Package | Installation |
---|---|
@stormid/validate |
|
Code
<form class="form js-validate" action="#"><p class="push-bottom">All fields are required unless marked as optional.</p><fieldset class="fieldset"><legend class="legend">Your details</legend><div class="form-row"><label for="fname" class="label">First Name</label><span class="error-message" data-valmsg-for="fname"></span><input data-val="true" data-val-required="First name must not be empty" autocomplete="given-name" class="input" id="fname" name="fname"/></div><div class="form-row"><label for="lname" class="label">Last Name</label><span class="error-message" data-valmsg-for="lname"></span><input data-val="true" data-val-required="Last name must not be empty" autocomplete="family-name" class="input" id="lname" name="lname"/></div><div class="form-row"><label for="aka" class="label">Also known as <span class="label__hint">Optional</span></label><input class="input" id="aka" autocomplete="nickname " name="aka"/></div><div class="form-row"><label for="email" class="label">Email</label><span class="error-message" data-valmsg-for="email"></span><input data-val="true" data-val-required="Email must not be empty" data-val-email="Email must be correct format" class="input" type="email" id="email" autocomplete="email" name="email"/></div></fieldset><fieldset class="fieldset"><legend class="legend">Your preferences</legend><div class="push-bottom--half">Please tick at least one option below.</div><span class="error-message push-bottom--half" data-valmsg-for="opts"></span><div class="checkbox"><input class="checkbox__input" id="opt1" name="opts" type="checkbox" data-val="true" data-val-required="Select at least one option"/><label class="checkbox__label" for="opt1">Option 1</label></div><div class="checkbox"><input class="checkbox__input" id="opt2" name="opts" type="checkbox" data-val="true" data-val-required="Select at least one option"/><label class="checkbox__label" for="opt2">Option 2</label></div><div class="checkbox"><input class="checkbox__input" id="opt3" name="opts" type="checkbox" data-val="true" data-val-required="Select at least one option"/><label class="checkbox__label" for="opt3">Option 3</label></div><div class="checkbox"><input class="checkbox__input" id="opt4" name="opts" type="checkbox" data-val="true" data-val-required="Select at least one option"/><label class="checkbox__label" for="opt4">Option 4</label></div><div class="checkbox"><input class="checkbox__input" id="opt5" name="opts" type="checkbox" data-val="true" data-val-required="Select at least one option"/><label class="checkbox__label" for="opt5">Option 5</label></div></fieldset><fieldset class="fieldset"><legend class="legend">Terms and conditions</legend><div class="checkbox"><input data-val="true" data-val-required="You must agree to proceed" class="checkbox__input" id="tcs" name="tcs" type="checkbox"/><label class="checkbox__label" for="tcs">I have read and agree to the <a href="#">terms and conditions</a></label><span class="field-validation-error" data-valmsg-for="tcs"></span></div></fieldset><button type="submit" class="btn">Submit</button></form>
import validate from '@stormid/validate';
validate('.js-validate');
Acceptance criteria
The following is a list of example acceptance criteria to test against when using this pattern. These critera should test that the specific markup requirements are met, and that the validation behaves visually and functionally as expected.
For validation in developer tools / web inspector
- All form
<input>
,<select>
or<textarea>
elements must have a matching<label>
elements oraria-label
- Any inputs that are related to each other (eg. address inputs) should be grouped inside a
<fieldset>
element with a<legend>
element describing the group - Error messages should not have
role="alert"
oraria-live
attributes - Error messages should be associated with an input. The invalid
<input>
,<select>
or<textarea>
should have anaria-describedby
attribute which matches the ID of the error message to achieve this - Required
<input>
,<select>
or<textarea>
elements should have anaria-required
attribute - Any invalid
<input>
,<select>
or<textarea>
elements should have anaria-invalid="true"
attribute
For visual validation
- All form inputs should have a clearly visible focus style which meets accessibility contrast requirements
- Required and optional fields should be visibly indicated and announced to a screen reader as such
- Error messages must be visible and announced via screen reader
For functional validation
- All inputs must be reachable and function correctly via keyboard
- Form inputs collecting certain types of user-specific information should use autocomplete
- At least one error prevention technique should be used: validation on submission with error messages allowing the user to correct them; or subsmisisons are reversible; or user input can be reviewed and confirmed before submission
- Error messages which update as you type should not be announced a screen reader to avoid excess noise
References
- https://www.davidmacd.com/blog/test-aria-describedby-errormessage-aria-live.html
- https://dequeuniversity.com/checklists/web/form-validation-feedback
- https://www.w3.org/TR/WCAG21/#input-purposes
- https://webaim.org/standards/wcag/checklist
- https://webaim.org/techniques/forms/
- https://design-system.service.gov.uk/patterns/validation/
- https://design-system.service.gov.uk/components/error-message/
- https://github.com/stormid/components/tree/master/packages/validate
- https://github.com/stormid/components/pull/166