validation in order to remove the disabled status of the dependent field
Demo
A feature demo can be found here.
Documentation
Importing the Validation
class queries the current page for <form>
elements
and disables the default browser constraint validation
by adding a novalidate
attribute to that element.
The default behavior is to validate each field when their value is updated,
and validate the entire form when it is submitted. This can be changed to only
validate on form submission by setting onlyOnSubmit
to true
on the
instance.
Once a field is marked invalid, it will always re-validate when its value is
changed regardless of the onlyOnSubmit
value.
required
fields are first tested for blank. If this check is passed, fields are then tested based on theirtype
attribute value if applicable. (Described below.) Lastly, the field will test for a user supplied pattern if present.
Required Fields
Usually, the majority of fields in a form need validation. To make setup
easier, instances of the Validation class have a default reqAll
value of true
. This marks all fields that meet the following criteria
required and needing validation:
- Have a
name
attribute. - Not
disabled
.
Indivudual fields can then be excluded from validation as described below.
This functionality can be inverted by setting reqAll
to false
,
and manually giving your required fields a required
attribute.
<div class="form-group">
<label for="text">Text</label>
<input required id="text" type="text" name="text">
</div>
<input>
type
attribute values of checkbox
and radio
only need one option to have the
required
attribute, however, it is recommended to add it to all options for
consistency. More information on checkbox and radio fields can be found below.
Required Indicator
A <span>
tag with class of required__indicator
containing an asterisk(*)
character will be inserted beforeend
of a required field's <label>
element.
This indicator will be inserted to the <legend>
element of checkbox
and
radio
<input>
types if present as described below.
The indicator can be disabled or customized as described in Form Options.
Markup
The Validation
class requires the following for each required field:
- All form fields to be wrapped in an element with the
form-group
class. - Do NOT nest the required field in a
<label>
element. - Unique, matching values of the required field's
id
and its<label>
'sfor
attribute. - A unique
name
attribute on the required field.checkbox
andradio
<input>
types should share the same uniquename
attribute.
When a field fails validation the wrapper
.form-group
element will receive aninvalid
CSS class. Use this to write your own CSS to indicate an invalid state.
<div class="form-group">
<label for="text">Text</label>
<input id="text" type="text" name="text">
</div>
Checkbox and Radio Fields
- Wrap all options in a
<fieldset>
element and add theform-group
class to it instead of the individual options. - The
<legend>
tag may be used to give the option set a heading. - Field Options are shared amongst all inputs in a check or
radio group. Your options only need to be applied to one of the inputs in the
group that shares a
name
attribute.
<fieldset class="form-group">
<legend>Check Group</legend>
<span class="form-group__item">
<input data-validation='{"minChecks": 2, "optional": true}' id="checkbox-1" type="checkbox" name="checks">
<label for="checkbox-1">Checkbox 1</label>
</span>
<span class="form-group__item">
<input id="checkbox-2" type="checkbox" name="checks">
<label for="checkbox-2">Checkbox 2</label>
</span>
<span class="form-group__item">
<input id="checkbox-3" type="checkbox" name="checks">
<label for="checkbox-3">Checkbox 3</label>
</span>
</fieldset>
Select Fields
Required <select>
elements should contain an <option>
with the selected
attribute and an empty value
attribute. If not present the element will pass
validation even while being required.
<div class="form-group">
<label for="select">Select</label>
<select id="select" name="select">
<option selected value="">Choose an Item</option>
<option>1</option>
<option>2</option>
<option>3</option>
</select>
</div>
Password Fields
When an <input>
element with a type
attribute of password
is detected on the
page, a required Password Confirm field will auto generate after its parent
.form-group
wrapper.
The markup for this field is a duplicate of the original input's parent
.form-group
wrapper. The id
and name
attributes of the <input>
element,
and the for
attribute of the <label>
element will have their values set to
password-confirm
.
This functionality can be disabled by settting passConfirm
to false
.
A Password field with the markup of
<div class="form-group">
<label for="password">Password</label>
<input id="password" type="password" name="password">
</div>
will generate a Password Confirm field with the markup of
<div class="form-group">
<label for="password-confirm">Password Confirm<span class="required__indicator">*</span></label>
<input id="password-confirm" type="password" name="password-confirm">
</div>
The Password field is tested that it matches its corresponding Password Confirm field when the Password Confirm field contains a non-blank value.
The Password Confirm field is always tested that it matches its corresponding Password field.
Custom Form Controls
Custom form controls can be validated by informing the ValidationField class what you want to check against as the value for your control. You can determine validity based on:
- Existence of an element.
- TextContent of an element.
- Existence of an attribute.
- Value of an attribute.
To validate a custom form control, add a data-validation
attribute to an
element of the control. The value should be a single quoted JSON object with
valueSrc
as a property.
The element that the
data-validation
attribute is added to MUST have a uniqueid
andname
attribute. Having an associatedlabel
/legend
tag with afor
attribute is optional, but recommended.
The value of the property should be an array with up to three items.
valueSrc[0]:
A CSS selector to target the element to reference for value.
valueSrc[1]:
The keyword attribute
, attributeValue
, exists
, or
textContent
.
valueSrc[2]:
If using attribute
or attributeValue
, the attribute to
reference. If using exists
, a CSS selector relative to valueSrc[0]
as the
parent.
valueSrc
can be combined with pattern
and patternMessage
field options to check for specific values and output custom error messages.
See the examples below.
Existence of an Element
Determine validity based on whether an element exists or not.
Valid if... the target element exists.
The following example checks for the presence of in image element that is a child of the element with an id of 'custom-control'.
<div class="form-group">
<label for="custom-control">Custom Form Control</label>
<div data-validation='{"valueSrc": ["#custom-control", "exists", "img"]}' id="custom-control" name="custom_control"></div>
</div>
The third item in the
valueSrc
array can be any valid CSS selector string thatquerySelector
can parse. e.x.:scope > img
TextContent of an Element
Use the target element's textContent
to determine validity. Useful when using contenteditable
.
Valid if... the target element's textContent property is a non-empty string.
The following example checks if the element with an id of 'custom-control' has
a non-empty string textContent
property.
<div class="form-group">
<label for="custom-control">Custom Form Control</label>
<div data-validation='{"valueSrc": ["#custom-control", "textContent"]}' id="custom-control" name="custom_control" contenteditable></div>
</div>
Existence of an Attribute
Use the target element's specified attribute existence to determine validity.
Valid if... the target element's specified attribute exists.
The following example checks if the element with an id of 'custom-control' has
a title
attribute.
<div class="form-group">
<label for="custom-control">Custom Form Control</label>
<div data-validation='{"valueSrc": ["#custom-control", "attribute", "title"]}' id="custom-control" name="custom_control"></div>
</div>
The value of a boolean attribute will evaluate as
false
and invalid unless it is a non-empty string. When using this option, the attribute must use thechecked="checked"
(true, valid) andchecked=""
(false, invalid) form and notchecked
.checked
will evaluate as false and invalid whether present or not.
Value of an Attribute
Use the target element's specified attribute value to determine validity.
Valid if... the value of the target's specified attribute is a non-empty string.
The following example checks if the element with an id of 'custom-control' has
a title
attribute with a non-empty string value.
<div class="form-group">
<label for="custom-control">Custom Form Control</label>
<div data-validation='{"valueSrc": ["#custom-control", "attributeValue", "title"]}' id="custom-control" name="custom_control"></div>
</div>
The value of a boolean attribute will evaluate as
false
and invalid unless it is a non-empty string. When using this option, the attribute must use thechecked="checked"
(true, valid) andchecked=""
(false, invalid) syntax. If you need to check a boolean attribute useattribute
.
Form Options
- invalidClass
- messageClass
- onlyOnSubmit
- onSuccess
- passConfirm
- reqAll
- reqIndicator
- reqIndicators
- reqIndicatorClass
- valFieldsOn
Default instance options can be overwritten by adding a single quoted
data-validation
attribute on the <form>
being validated. Its value must be
a properly formatted JSON object.
<form data-validation='{"onlyOnSubmit": true, "reqIndicator": "❗️"}'>
<div class="form-group">
<label for="text">Text</label>
<input id="text" type="text" name="text">
</div>
<div class="form-group">
<button type="submit">Submit</button>
</div>
</form>
invalidClass
Default: invalid
The class assigned to the parent <div class="form-group" />
wrapper of the
invalid field.
messageClass
Default: invalid__message
The class assigned output message of the invalid field.
onlyOnSubmit
Default: false
Only validate the form on submission. A setting of true
will disable
individual field validation. Regardless of this setting fields will always
validate on the valFieldsOn
value while they are invalid.
onSuccess
Default: null
Run a script when the form is submited and all fields pass validation. A non truthy value will cancel the form's default action.
<form data-validation='{"onSuccess": "save()"}'>...</form>
passConfirm
Default: true
Automatically create a confirm password field. The markup from the user created
field with a type="password"
attribute will be duplicated and modifed, then
inserted after the original field.
<form data-validation='{"passConfirm": true}'>...</form>
reqAll
Default: true
Automatically add a required
attribute to all <input>
, <select>
, and
<textarea>
tags in the <form>
. This allows you to skip marking individual
fields as required
in your markup.
Individual fields can be excluded from validation by adding a
data-validation
attribute to a field that's value is a JSON object with anoptional
property value set totrue
.
<div class="form-group">
<label for="not-required">Not Required</label>
<input data-validation='{"optional": true}' id="not-required" type="text" name="not_required">
</div>
reqIndicator
Default: *
The string to render after the label text to indicate to the user that the field is required.
reqIndicators
Default: true
Enable the output of reqIndicator
strings.
If set to false
, you can target all field labels with the CSS selector below
to apply a custom style.
.form-group:has([required])
:where(label:has(:not(.form-group__item)), legend) {
/* Your styles here. */
}
reqIndicatorClass
Default: required__indicator
The class assigned to the <span>
wrapper of the outputted reqIndicator
.
valFieldsOn
Default: input
The event that triggeers individual field validation. Value can be any
JavaScript event, but it is recommended to try
blur
,
change
,
or input
.
Individual field validation can be disable by setting
onlyOnSubmit
to true.
Field Options
Individual fields can be passed options to customize their behavior by adding a
single quoted data-validation
attribute to a field. Its value must be a
properly formatted JSON object with the properties and values below.
<div class="form-group">
<label for="custom">Custom Regex</label>
<input data-validation='{"optional": true,
"pattern": "^[0-9]*$",
"patternMessage": "This field must only contain numbers."
}'
id="custom" type="text" inputmode="numeric" name="custom">
</div>
dependent
Default: null
Setting the dependent
value of one field to another field's name
attribute
value will disable the field when its dependent field does not contain a
valid value.
<figure class="form-group">
<label for="dependent-parent">Dependent Parent</label>
<input id="dependent-parent" type="text" name="dependent_parent">
<figcaption>This field dynamically enables/disables the 'Dependent Child' field if it has a value.</figcaption>
</figure>
<figure class="form-group">
<label for="dependent-child">Dependent Child</label>
<input data-validation='{"dependent": "dependent_parent"}' id="dependent-child" type="text" name="dependent_child">
<figcaption>This field dynamically enables/disables if the 'Dependent Parent' field has a value.</figcaption>
</figure>
maxCount (Checkboxes Only)
Default: null
Checkbox groups with the maxCount
property set to an integer will fail validation
if the number of checked inputs is over this limit.
See here for more information on how to apply options to checkboxes.
minCount (Checkboxes Only)
Default: 1
Checkbox groups with the minCount
property set to an integer will fail validation
if the number of checked inputs is under this limit.
See here for more information on how to apply options to checkboxes.
optional
Default: false
Fields with the optional
property set to true
will pass vaidation when
blank. They still will be processed for validation when they contain a value
based on the input
type
attribute, or if a user pattern
is specified.
pattern
Default: null
A regular expression to test the field's value against. This string is also
copied and added to the field as a native pattern
attribute. It is recommended to also provide an error message to display when
the value does not match pattern
by providing a patternMessage
.
patternMessage
Default: null
An error message to display when the field fails the custom validation test
provided by pattern
.
If not provided with
pattern
the field will be marked as invalid, but no message will output when the pattern does not match.
valueSrc
Default: null
Used to validate custom form controls. See here for more information.