Error Messages and Validation
Validation errors should come with specific messages that tell the user exactly what to fix. "This field is required" is not a good message for an email input field; "Enter your email address" is more specific.
Provide a summary of the validation errors at the top of the form. Each error message should be connected to an input field using aria-describedby
, and should include a link to skip directly to that field. Error messages should not appear below the inputs or submit button, as screen reader users will hear them late in the sequence, and autocomplete dropdowns often obscure the message.
Required <select>
dropdowns must not include an empty value, or the browser will fail to report the validation error.
Further reading on error messages
- Exposing Field Errors, Adrian Roselli discusses ARIA and screen reader behavior related to form field error messages, including video demonstrations of JAWS behavior
- Microcopy: The Complete Guide, by Kinneret Yifrah
- Form Design Patterns, by Adam Silver
Using the Error Summary component
Subject to change; this feature is still in development. See #2102122
The error summary component lists required & invalid form fields as links leading directly to the invalid inputs, with link text generated from the fields' labels and aria-descriptions (if present).
By adding the error list as a ViewChild of the component containing the form, it is possible to check for errors and scroll to / focus on the list rather than disabling the form's submit button:
<eg-error-summary #errors></eg-error-summary> ... <button (click)="canSave ? save() : errors.checkErrors()">Save</button>
(In addition to changing the click action and color of the button, you should also add a warning icon and/or change the button text, in case the user can't perceive color changes.)
If the containing component does not already have a mechanism to check for valid
form submissions, you can use getErrors()
to refresh the list and hasErrors()
to
see whether the error list is empty.
You will need to call getErrors()
when field values change, or the submit button
will never return to its initial state.
Selectors for the container and the invalid fields can be provided using inputs to the component, so it can be used without an enclosing form element. For example, see the included changes to the patron edit form:
<eg-error-summary #errorList [containerSelector]="'.patron-edit-container'"> </eg-error-summary>
The errors do not have to be form inputs. Any selector can be provided as an input to the error summary. This is useful when the inputs are not available until an Edit button is clicked, as in the holdings editor:
<eg-error-summary #errorList [errorSelector]="'.changed.invalid .card-header'"> </eg-error-summary>
The error summary can list errors across NgbNav tabs if the nav contents are not destroyed on tab change; see https://ng-bootstrap.github.io/#/components/nav/examples#keep-content. In this case, the summary should be placed outside the nav component. The error list will be subdivided by tab label, and clicking an inactive tab's error link will first switch tabs, then focus on the error field.