afova v1.0.3
afova
afova (accessible form validation) is a progressive enhancement of the web browsers client-side HTML form constraint validation.
afova will allow you to:
- pick up any of the constraining attributes of HTML input elements (
required,type,step,pattern,min,max,minlength,maxlength) and show constraint violation messages to the user, - describe violation messages with corresponding
dataattributes (data-required,data-type,data-step,data-pattern,data-min,data-max,data-minlength,data-maxlength,data-bad-input), - use placeholders within the violation messages to refer to the current user input (placeholder is
{{input}}) and to the violated constraint setting (placeholder is{{constraint}}), - style constraint violation messages with CSS,
- in addition to showing the violation messages along with the input elements, summarize all violation messages in a separate list inside of the form,
- do custom HTML input element validation (sync and async),
- do HTML form validation (sync and async) to validate input elements of a form in relation to each other, and
- prevent multiple submits of a form that is already in an ongoing submitting process.
You can use the afova library as a minified version without a bundler on your web page (it´s an ESM import), or for more complex scenarios integrate it with a bundler. Read more about that under afova usage.
Below is an example of how afova allows to define constraint violation messages:
<form>
<label
>A min length and max length text input
<input
type="text"
required
data-required="Please provide a value"
minlength="5"
data-minlength="Hey, {{input}} is not long enough. Your input should have at least {{constraint}} characters."
maxlength="8"
data-maxlength="Sorry, {{input}} is too long. Please do not enter text with more than {{constraint}} characters."
pattern="[0-9]*"
data-pattern="Only digits are allowed: {{constraint}}"
/>
</label>
<input type="submit" value="Submit the form" />
<input type="reset" value="Reset the form" />
</form>afova will identify the constraints assigned to input elements, validate the form during submit, and report constraint violations to the user.
The above example will be transformed by afova into the following HTML:
<form id="afova-sJM4xyJx_4JltktdSKg7q" novalidate="">
<label
id="afova-4NznJ3zynpcxg0yF1ZKXI"
class="afova-context"
for="afova-HS2YEDxawe9CuzVYyZVqd"
>A min length and max length text input
<input
type="text"
required=""
data-required="Please provide a value"
minlength="5"
data-minlength="Hey, {{input}} is not long enough. Your input should have at least {{constraint}} characters."
maxlength="8"
data-maxlength="Sorry, {{input}} is too long. Please do not enter text with more than {{constraint}} characters."
pattern="[0-9]*"
data-pattern="Only digits are allowed: {{constraint}}"
id="afova-HS2YEDxawe9CuzVYyZVqd"
class="afova-control"
/>
</label>
<input type="submit" value="Submit the form" />
<input type="reset" value="Reset the form" />
</form>Trying to submit the form without providing a text value will violate the required constraint. afova will prevent the submit and instead provide a constraint violation message in the following form:
<form id="afova-fpVF2baWLLZaRqSGgf9oZ" novalidate="">
<label
id="afova-KDJFSNnl7sJXJMiRqhgvF"
class="afova-context afova-active"
for="afova-HssNc_nNBlq_vchMx3AG9"
>A min length and max length text input
<div
id="afova-HssNc_nNBlq_vchMx3AG9-afova-message-container"
class="afova-message-container"
>
<div
class="afova-message"
afova-message-for="afova-HssNc_nNBlq_vchMx3AG9"
>
Please provide a value
</div>
</div>
<input
type="text"
required=""
data-required="Please provide a value"
minlength="5"
data-minlength="Hey, {{input}} is not long enough. Your input should have at least {{constraint}} characters."
maxlength="8"
data-maxlength="Sorry, {{input}} is too long. Please do not enter text with more than {{constraint}} characters."
pattern="[0-9]*"
data-pattern="Only digits are allowed: {{constraint}}"
id="afova-HssNc_nNBlq_vchMx3AG9"
class="afova-control"
aria-invalid="true"
aria-errormessage="afova-HssNc_nNBlq_vchMx3AG9-afova-message-container"
/>
</label>
<input type="submit" value="Submit the form" />
<input type="reset" value="Reset the form" />
</form>For more details about constraint validation please refer to:
Bundler
When using a bundler, add afova to your project with the command:
npm i afovaThen import afova into your JavaScript/TypeScript setup:
import { afova } from 'afova'
//initialize by creating an afova object named afv with default settings
const afv = afova();HTML page without bundler
When working without a bundler, download the ESM script afova.min.js and put it into the assets folder of your website (or any other folder where your script dependencies are located).
Integrate afova into your web pages as follows:
<script type="module">
import { afova } from "/assets/afova.min.js";
//initialize by creating an afova object named afv with default settings
var afv = afova();
</script>The afova object
When creating the afova object by calling afova(), all forms that are available on the web page are traversed and afova will take over form validation for those forms.
The afova object offers a clear() method that can be used in situations where you have to remove event listeners and CSS class assignments introduced by afova from the web page.
Settings
JavaScript
The afova object can be initialized with an optional settings object, that allows to hook into the form validation process:
{
selector?: string;
formMessageSelector?: string;
validateOnChange?: boolean;
focusOnFirstError?: boolean;
onSubmit?: (event: SubmitEvent) => void;
onReset?: (event: Event) => void;
onInvalid?: (event: SubmitEvent) => void;
onValid?: (event: SubmitEvent) => void;
onValidateControl?: (control: HTMLInputElement) => void
onAsyncValidateControl?: (control: HTMLInputElement) => Promise<void>
onValidateControlError?: (control: HTMLInputElement, error: unknown) => void
onBeforeValidateForm?: (form: HTMLFormElement) => void
onValidateForm?: (form: HTMLFormElement) => void
onAsyncValidateForm?: (form: HTMLFormElement) => Promise<void>
onValidateFormError?: (form: HTMLFormElement, error: unknown) => void
}Properties of the settings object and their meaning:
selector?: stringConfigure the selector being used during construction of the afova object to identify the forms to validate. Default isform.formMessageSelector?: stringConfigure the selector being used during construction of the afova object to identify the form message container. To show constraint violation messages not only along with the invalid input elements of the form, but also in a list inside of the form, you can have a form message container. By default the container is identified with the CSS class.afova-form-message-containerduring construction of the afova object. afova will search for the container inside of the form and summarize all constraint violation messages there. The form message container is optional, because violation messages anyway will be displayed along with the invalid input element.focusOnFirstError?: booleanThe default value istrue. afova will focus the first invalid input element during validation of the form in that case.validateOnChange?: booleanThe default isfalse. When set totrue, afova will validate each input element of the form when theonChangeevents of the HTML input elements fire, and not only during form submit.onSubmit: (event: SubmitEvent) => voidThe hook is called by afova when the submit event of the form fired and the form is successfully validated. TheSubmitEventis prevented when this hook is defined. The submit needs to be implemented inside of this hook in that case.onReset?: (event: Event) => voidafova will call this hook when the reset event of the form fired.onInvalid?: (event: SubmitEvent) => voidafova will call this hook the submit event of the form fired but the form is invalid. The form will not be submitted in that case.onValid?: (event: SubmitEvent) => voidafova will call this hook when the submit event of the form fired and the form is valid. The hok is called before theonSubmithook.onValidateControl?: (control: HTMLInputElement) => voidafova will call this hook for each input element during form validation. The hook can be used to invalidate the input element by setting a custom validation message withcontrol.setCustomValidity(). The hook is only called after the successful validation of all constraints of the input element, which means for the hook is not called for an already invalid input element.onAsyncValidateControl?: (control: HTMLInputElement) => Promise<void>afova will call this async hook for each input element during form validation. The hook must return a promise. The hook can be used to invalidate the input element by setting a custom validation message withcontrol.setCustomValidity(). The hook will only be called after the successful validation of all constraints for the input element and after theonValidateControlhook.onValidateControlError?: (control: HTMLInputElement, error: unknown) => voidafova will call the error handling hook when an exception occurs during input element validation. When this handler is defined, the error is catched bys afova and given to the handler. When the handler is not defined, the error is thrown by afova.onBeforeValidateForm?: (form: HTMLFormElement) => voidafova will call this hook before starting to validate a form.onValidateForm?: (form: HTMLFormElement) => voidafova will call the hook after successful validation of all input elements of the form. The hook can be used to validate input elements in relation to each other.onAsyncValidateForm?: (form: HTMLFormElement) => Promise<void>afova will call this async hook after successful validation of all input elements of the form and after theonValidateFormhook. The hook must return a promise. The hook can be used to validate input elements in relation to each other.onValidateFormError?: (form: HTMLFormElement, error: unknown) => voidafova will call this hook hook when an exception occurs during form validation. When this handler is defined, the error is catched by afovaand given to the handler. When the handler is not defined, the error is thrown by afova.
HTML
The following attributes are available to describe constraint violation messages:
data-badinputThe browser is unable to handle the input value, for example when the required type of the input element is a number but the user provided a alphabetic characters.data-patternThe value of a field doesn´t comply to the pattern of thepatternattribute.data-maxThe number value of a field is greater than the value of themaxattribute.data-minThe number value of a field is less than the value of theminattribute.data-stepThe number value of field is not evenly divisable by the value of thestepattribute.data-maxlengthThe value of a field has more characters than defined by the attributemaxlength.data-minlengthThe value of a field has less characters than defined by the attributeminlength.data-typeThe value of a field dosn´t comply to thetypeattribute.data-requiredA value of a field that is required due to therequiredattribute is missing.
Assigning your constraint violation messages is a good way to have internationalized messages and generally recommended. You can use the placeholders to refer to certain control properties within your violation messages, like:
{{input}}for current user input,{{constraint}}for the violated constraint, and{{type}}for the controls value of the type attribute.
afova will apply English fallback messages in case you do not use your own constraint violation messages,
Summarizing messages for the form
All constraint violation messages of an entire form can be summarized and listed inside of a form message container. The form message container must be inside of the validated form and is described to afova by assigning the CSS class afova-form-message-container.
E.g., when you defined a form message container like in the example below:
<form>
<div class="afova-form-message-container" style="display: none">
<strong>The form has validation failures</strong>
</div>
<label
>A min length and max length text input
<input
type="text"
required
data-required="Please provide a value"
minlength="5"
data-minlength="Hey, {{input}} is not long enough. Your input should have at least {{constraint}} characters."
maxlength="8"
data-maxlength="Sorry, {{input}} is too long. Please do not enter text with more than {{constraint}} characters."
pattern="[0-9]*"
data-pattern="Only digits are allowed: {{constraint}}"
/>
</label>
<input type="submit" value="Submit the form" />
<input type="reset" value="Reset the form" />
</form>When trying to submit that form without providing an input value, afova will produce the following HTML:
<form
id="afova-K9OUvdZfjcP2wW24A0ZlA"
novalidate=""
afova-form-message-container-id="afova-xDRp9MC3iiVLh7ZOC2IJZ"
>
<div
class="afova-form-message-container"
style=""
id="afova-xDRp9MC3iiVLh7ZOC2IJZ"
>
<strong>The form has validation failures</strong>
<ul class="afova-message-list">
<li
afova-message-for="afova-Iiw91SPozRG0mwbemqhWz"
class="afova-collected-message"
>
<div class="afova-message-label">
A min length and max length text input
</div>
<a href="#afova-Iiw91SPozRG0mwbemqhWz" class="afova-message"
>Please provide a value</a
>
</li>
</ul>
</div>
<label
id="afova-t9h439TQ-TeH4vWFOcGTi"
class="afova-context afova-active"
for="afova-Iiw91SPozRG0mwbemqhWz"
>A min length and max length text input
<div
id="afova-Iiw91SPozRG0mwbemqhWz-afova-message-container"
class="afova-message-container"
>
<div
class="afova-message"
afova-message-for="afova-Iiw91SPozRG0mwbemqhWz"
>
Please provide a value
</div>
</div>
<input
type="text"
required=""
data-required="Please provide a value"
minlength="5"
data-minlength="Hey, {{input}} is not long enough. Your input should have at least {{constraint}} characters."
maxlength="8"
data-maxlength="Sorry, {{input}} is too long. Please do not enter text with more than {{constraint}} characters."
pattern="[0-9]*"
data-pattern="Only digits are allowed: {{constraint}}"
id="afova-Iiw91SPozRG0mwbemqhWz"
class="afova-control"
aria-invalid="true"
aria-errormessage="afova-Iiw91SPozRG0mwbemqhWz-afova-message-container"
/>
</label>
<input type="submit" value="Submit the form" />
<input type="reset" value="Reset the form" />
</form>Notice the label text of each control is extracted and displayed along with the constraint violation message inside of the form message container. To have more control over what label information is shown in the form message container you can put a marker on the desired text in your form by assigning the CSS class afova-label.
Styling and identifiying
afova does not come with any CSS styles, you have to do the styling yourself. The following CSS class names are assigned during validation processing or can be used to activate afova functionality:
.afova-contextafova searches for a context for every validated input element. By default this is thelabelelement wrapping the control. afova assigns the CSS classafova-contextto the context element. You can decide to use a different wrapping context by assigning theafova-contextclass yourself, which can make sense for fieldsets of radio buttons or checkboxes..afova-groupThe CSS classafova-groupcan be used to bundle constraint violation messages in front of a group of input elements. A good use case are radio buttons or checkboxes that belong together. Do it wrapping the input elements into adivand assign the CSS classafova-groupto thediv..afova-activeA context with an invalid input element has the CSS classafova-activeassigned to it. The class is removed once the control becomes valid again..afova-message-containerWhen an input element becomes invalid because of a constraint violation, a container for violation messages is inserted right before the control. The container will have the CSS classafova-message-container. Once the input element becomes valid again, the message container is removed..afova-messageEach violation message inside of the message container has the CSS classafova-messageassigned to it..afova-controlEvery input element validated by afova has the CSS classafova-controlassigned to it..afova-form-message-containerDefine a collector for summarizing all constraint violation messages of a form by assigning the CSS classafova-form-message-container..afova-labelThe message collector will show the control´s label together with the constraint violation message. By default the complete label text will be extracted by afova. To have more control over what text is shown in the collector, assign the classafova-labelto any text content along with the validated input element..afova-message-labelThe label information inside of the message collector will have the CSS classafova-message-labelassigned to it.
Accessibility
idEvery input element and every form observed by afova will get anidassigned if it doesn´t have one (you can use your own ids).forWhen a wrapping label of an input element does not have theforattribute pointing to theidof the input element, theforattribute will be assigned by afova.aria-invalidAn invalid input element has the attributearia-invalidassigned to it.aria-errormessageAn invalid input element has the attributearia-errormessagepointing to theidof the associated message container.
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
3 years ago