Form validation


Purpose

Provides generic validation and error message handling for Web forms.

Examples using regular or specialized validation

Contact information
View code

Consider adding an aria-hidden="true" attribute to <strong class="required"> (i.e. <strong class="required" aria-hidden="true">) in required field labels. Hardcoding it will prevent screen readers from announcing "required" twice in the noscript and basic HTML versions of the page. The form validation plugin automatically adds the attribute to the JavaScript version. Don't use the attribute in required <legend> elements.

<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<div class="form-group">
			<label for="title1" class="required"><span class="field-name">Title</span> <strong class="required">(required)</strong></label>
			<select class="form-control" id="title1" name="title1" autocomplete="honorific-prefix" required="required">
				<option label="Select a title"></option>
				<option value="dr">Dr.</option>
				<option value="esq">Esq.</option>
				<option value="mr">Mr.</option>
				<option value="ms">Ms.</option>
			</select>
		</div>
View code

Consider adding an aria-hidden="true" attribute to <strong class="required"> (i.e. <strong class="required" aria-hidden="true">) in required field labels. Hardcoding it will prevent screen readers from announcing "required" twice in the noscript and basic HTML versions of the page. The form validation plugin automatically adds the attribute to the JavaScript version. Don't use the attribute in required <legend> elements.

<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<div class="form-group">
			<label for="fname1" class="required"><span class="field-name">First name</span> <strong class="required">(required)</strong></label>
			<input class="form-control" id="fname1" name="fname1" type="text" autocomplete="given-name" required="required" data-rule-minlength="2" />
		</div>
View code

Consider adding an aria-hidden="true" attribute to <strong class="required"> (i.e. <strong class="required" aria-hidden="true">) in required field labels. Hardcoding it will prevent screen readers from announcing "required" twice in the noscript and basic HTML versions of the page. The form validation plugin automatically adds the attribute to the JavaScript version. Don't use the attribute in required <legend> elements.

<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<div class="form-group">
			<label for="lname1" class="required"><span class="field-name">Last name</span> <strong class="required">(required)</strong></label>
			<input class="form-control" id="lname1" name="lname1" type="text" autocomplete="family-name" required="required" data-rule-minlength="2" />
		</div>
View code

Consider adding an aria-hidden="true" attribute to <strong class="required"> (i.e. <strong class="required" aria-hidden="true">) in required field labels. Hardcoding it will prevent screen readers from announcing "required" twice in the noscript and basic HTML versions of the page. The form validation plugin automatically adds the attribute to the JavaScript version. Don't use the attribute in required <legend> elements.

<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<div class="form-group">
			<label for="tel1" class="required"><span class="field-name">Telephone number (including area code)</span> <strong class="required">(required)</strong></label>
			<input class="form-control" id="tel1" name="tel1" type="tel" autocomplete="tel" required="required" data-rule-phoneUS="true" />
		</div>
View code

Consider adding an aria-hidden="true" attribute to <strong class="required"> (i.e. <strong class="required" aria-hidden="true">) in required field labels. Hardcoding it will prevent screen readers from announcing "required" twice in the noscript and basic HTML versions of the page. The form validation plugin automatically adds the attribute to the JavaScript version. Don't use the attribute in required <legend> elements.

<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<div class="form-group">
			<label for="pcodeca1" class="required"><span class="field-name">Postal code</span> <strong class="required">(required)</strong></label>
			<input class="form-control" id="pcodeca1" name="pcodeca1" type="text" autocomplete="postal-code" size="7" maxlength="7" required="required" data-rule-postalCodeCA="true" />
		</div>
View code
<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<div class="form-group">
			<label for="email1"><span class="field-name">Email address</span> (yourname@domain.com)</label>
			<input class="form-control" id="email1" name="email1" type="email" autocomplete="email" />
		</div>
View code
<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<div class="form-group">
			<label for="url1"><span class="field-name">Website URL (https://www.url.com)</span></label>
			<input class="form-control" id="url1" name="url1" type="url" autocomplete="url" />
		</div>
View code

Consider adding an aria-hidden="true" attribute to <strong class="required"> (i.e. <strong class="required" aria-hidden="true">) in required field labels. Hardcoding it will prevent screen readers from announcing "required" twice in the noscript and basic HTML versions of the page. The form validation plugin automatically adds the attribute to the JavaScript version. Don't use the attribute in required <legend> elements.

<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<div class="form-group">
			<label for="file1" class="required"><span class="field-name">File</span> <strong class="required">(required)</strong></label>
			<input id="file1" name="file1" type="file" required="required" />
		</div>
Other examples
View code
<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<div class="form-group">
			<label for="date1"><span class="field-name">Date</span><span class="datepicker-format"> (<abbr title="Four digits year, dash, two digits month, dash, two digits day">YYYY-MM-DD</abbr>)</span></label>
			<input class="form-control" id="date1" name="date1" type="date" data-rule-dateISO="true" />
		</div>
View code
<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<div class="form-group">
			<label for="time1"><span class="field-name">Time</span> (hh:mm)</label>
			<input class="form-control" id="time1" name="time1" type="time" />
		</div>
View code
<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
	...
	<div class="form-group">
		<label for="number1"><span class="field-name">Number</span> (between -a and 1 by step 0.1)</label>
		<input class="form-control" id="number1" name="number1" type="number" min="-1" max="1" step="0.1" />
	</div>
View code
<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<div class="form-group">
			<label for="an1"><span class="field-name">Alphanumeric</span> (at least 4 characters)</label>
			<input class="form-control" id="an1" name="an1" type="text" data-rule-alphanumeric="true" data-rule-minlength="4" />
		</div>
View code
<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<div class="form-group">
			<label for="numeric1"><span class="field-name">Numeric</span> (digits only)</label>
			<input class="form-control" id="numeric1" name="numeric1" type="number" data-rule-digits="true" />
		</div>
View code
<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<div class="form-group">
			<label for="letters1"><span class="field-name">Letters only</span> (maximum of 5 characters)</label>
			<input class="form-control" id="letters1" name="letters1" type="text" size="5" maxlength="5" data-rule-lettersonly="true" />
		</div>
View code
<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<div class="form-group">
			<label for="text1"><span class="field-name">Letters and punctuation only</span> (allowed punctuation: [. , ( ) "])</label>
			<input class="form-control" id="text1" name="text1" type="text" data-rule-letterswithbasicpunc="true" />
		</div>
View code
<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<div class="form-group">
			<label for="word1"><span class="field-name">Maximum of 10 words</span></label>
			<input class="form-control" id="word1" name="word1" type="text" data-rule-maxWords="10" />
		</div>
View code
<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<div class="form-group">
			<label for="word2"><span class="field-name">Minimum of 2 words</span></label>
			<input class="form-control" id="word2" name="word2" type="text" data-rule-minWords="2" />
		</div>
View code
<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<div class="form-group">
			<label for="word3"><span class="field-name">Between 2 and 10 words</span></label>
			<input class="form-control" id="word3" name="word3" type="text" data-rule-rangeWords="[2,10]" />
		</div>
View code
<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<div class="form-group">
			<label for="nowhitespace1"><span class="field-name">No white space</span></label>
			<input class="form-control" id="nowhitespace1" name="nowhitespace1" type="text" data-rule-nowhitespace="true" />
		</div>
View code
<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<div class="form-group">
			<label for="password1"><span class="field-name">Password</span> (between 5 and 10 characters)</label>
			<input class="form-control" id="password1" name="password1" type="password" autocomplete="new-password" maxlength="10" size="10" data-rule-rangelength="[5,10]" />
			<label for="passwordconfirm"><span class="field-name">Confirm your password</span></label>
			<input class="form-control" id="passwordconfirm" name="passwordconfirm" type="password" autocomplete="new-password" maxlength="10" size="10" data-rule-equalTo="#password1" />
		</div>
View code

Consider adding an aria-hidden="true" attribute to <strong class="required"> (i.e. <strong class="required" aria-hidden="true">) in required field labels. Hardcoding it will prevent screen readers from announcing "required" twice in the noscript and basic HTML versions of the page. The form validation plugin automatically adds the attribute to the JavaScript version. Don't use the attribute in required <legend> elements.

<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
			<div class="form-group">
				<div class="checkbox checkbox-standalone required">
					<label for="agree1"><input id="agree1" name="agree1" type="checkbox" required> <span class="field-name">I agree</span> <strong class="required">(required)</strong></label>
				</div>
			</div>
Favourite pets (required)
View code

It is recommended to use data-rule-required="true" vs required="required" as this avoids screen readers indicating that the first option is required.

<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<fieldset class="chkbxrdio-grp">
			<legend class="required"><span class="field-name">Favourite pets</span> <strong class="required">(required)</strong></legend>
			<div class="checkbox">
				<label for="animal1"><input type="checkbox" name="animal" value="1" id="animal1" data-rule-required="true" /> Dog</label>
			</div>
			<div class="checkbox">
				<label for="animal2"><input type="checkbox" name="animal" value="2" id="animal2" /> Cat</label>
			</div>
			<div class="checkbox">
				<label for="animal3"><input type="checkbox" name="animal" value="3" id="animal3" /> Fish</label>
			</div>
			<div class="checkbox">
				<label for="animal4"><input type="checkbox" name="animal" value="4" id="animal4" /> Other</label>
			</div>
		</fieldset>
Citizenship status (required)
View code

It is recommended to use data-rule-required="true" vs required="required" as this avoids screen readers indicating that the first option is required.

<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<fieldset class="chkbxrdio-grp">
			<legend class="required"><span class="field-name">Citizenship status</span> <strong class="required">(required)</strong></legend>
			<div class="radio">
				<label for="status1"><input type="radio" name="status" value="1" id="status1" data-rule-required="true" /> Canadian citizen</label>
			</div>
			<div class="radio">
				<label for="status2"><input type="radio" name="status" value="2" id="status2" /> Permanent resident</label>
			</div>
			<div class="radio">
				<label for="status3"><input type="radio" name="status" value="3" id="status3" /> Work permit</label>
			</div>
			<div class="radio">
				<label for="status4"><input type="radio" name="status" value="4" id="status4" /> Other</label>
			</div>
		</fieldset>

Example using custom pattern validation

If the pattern attribute is used alongside the data-rule attribute, the pattern validation will prevail; meaning that in the end you only get the generic validation error message that comes from the use of pattern. It is strongly recommended to use the data-msg attribute to customize the error message displayed by the pattern validation when the field is in error state.

View code

Consider adding an aria-hidden="true" attribute to <strong class="required"> (i.e. <strong class="required" aria-hidden="true">) in required field labels. Hardcoding it will prevent screen readers from announcing "required" twice in the noscript and basic HTML versions of the page. The form validation plugin automatically adds the attribute to the JavaScript version. Don't use the attribute in required <legend> elements.

<div class="wb-frmvld">
				<form action="#" method="get" id="validation-example">
					...
					<div class="form-group">
						<label for="custom1" class="required"><span class="field-name">Application number (one letter followed by six digits)</span> <strong class="required">(required)</strong></label>
						<input class="form-control" id="custom1" name="custom1" type="text" pattern="[A-Za-z][0-9]{6}" required="required" />
					</div>

Various examples of stacked and horizontal forms

Stacked checkboxes in a <li> pattern with implicit labels (required)
View code
<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<fieldset class="chkbxrdio-grp">
			<legend class="required"><span class="field-name">Stacked checkboxes in a <code>&lt;li&gt;</code> pattern with implicit labels</span> <strong class="required">(required)</strong></legend>
			<ul class="form-group list-unstyled">
				<li class="checkbox">
					<label for="example1a"><input type="checkbox" name="example1" value="1" id="example1a" required="required" />Apple</label>
				</li>
				<li class="checkbox">
					<label for="example1b"><input type="checkbox" name="example1" value="2" id="example1b" />Orange</label>
				</li>
				<li class="checkbox">
					<label for="example1c"><input type="checkbox" name="example1" value="3" id="example1c" />Kiwi</label>
				</li>
				<li class="checkbox">
					<label for="example1d"><input type="checkbox" name="example1" value="4" id="example1d" />Other</label>
				</li>
			</ul>
		</fieldset>
Note: The for attribute in the labels is optional for this pattern
Stacked radio buttons in a <li> pattern with implicit labels (required)
View code
<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<fieldset class="chkbxrdio-grp">
			<legend class="required"><span class="field-name">Stacked radio buttons in a <code>&lt;li&gt;</code> pattern with implicit labels</span> <strong class="required">(required)</strong></legend>
			<ul class="form-group list-unstyled">
				<li class="radio">
					<label for="example2a"><input type="radio" name="example2" value="1" id="example2a" required="required" />Apple</label>
				</li>
				<li class="radio">
					<label for="example2b"><input type="radio" name="example2" value="2" id="example2b" />Orange</label>
				</li>
				<li class="radio">
					<label for="example2c"><input type="radio" name="example2" value="3" id="example2c" />Kiwi</label>
				</li>
				<li class="radio">
					<label for="example2d"><input type="radio" name="example2" value="4" id="example2d" />Other</label>
				</li>
			</ul>
		</fieldset>
Note: The for attribute in the labels is optional for this pattern
Stacked checkboxes in a <div> pattern with implicit labels (required)
View code
<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<fieldset class="chkbxrdio-grp">
			<legend class="required"><span class="field-name">Stacked checkboxes in a <code>&lt;div&gt;</code> pattern with implicit labels</span> <strong class="required">(required)</strong></legend>
			<div class="checkbox">
				<label for="example3a"><input type="checkbox" name="example3" value="1" id="example3a" required="required" />Apple</label>
			</div>
			<div class="checkbox">
				<label for="example3b"><input type="checkbox" name="example3" value="2" id="example3b" />Orange</label>
			</div>
			<div class="checkbox">
				<label for="example3c"><input type="checkbox" name="example3" value="3" id="example3c" />Kiwi</label>
			</div>
			<div class="checkbox">
				<label for="example3d"><input type="checkbox" name="example3" value="4" id="example3d" />Other</label>
			</div>
		</fieldset>
Note: The for attribute in the labels is optional for this pattern
Stacked radio buttons in a <div> pattern with implicit labels (required)
View code
<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<fieldset class="chkbxrdio-grp">
			<legend class="required"><span class="field-name">Stacked radio buttons in a <code>&lt;div&gt;</code> pattern with implicit labels</span> <strong class="required">(required)</strong></legend>
			<div class="radio">
				<label for="example4a"><input type="radio" name="example4" value="1" id="example4a" required="required" />Apple</label>
			</div>
			<div class="radio">
				<label for="example4b"><input type="radio" name="example4" value="2" id="example4b" />Orange</label>
			</div>
			<div class="radio">
				<label for="example4c"><input type="radio" name="example4" value="3" id="example4c" />Kiwi</label>
			</div>
			<div class="radio">
				<label for="example4d"><input type="radio" name="example4" value="4" id="example4d" />Other</label>
			</div>
		</fieldset>
Note: The for attribute in the labels is optional for this pattern
Horizontal checkboxes in a <li> pattern with explicit labels (required)
View code
<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<fieldset class="chkbxrdio-grp">
			<legend class="required"><span class="field-name">Horizontal checkboxes in a <code>&lt;li&gt;</code> pattern with explicit labels</span> <strong class="required">(required)</strong></legend>
			<ul class="form-inline list-unstyled">
				<li class="label-inline">
					<input type="checkbox" name="example5" value="1" id="example5a" required="required" />
					<label for="example5a">Apple</label>
				</li>
				<li class="label-inline">
					<input type="checkbox" name="example5" value="2" id="example5b" />
					<label for="example5b">Orange</label>
				</li>
				<li class="label-inline">
					<input type="checkbox" name="example5" value="3" id="example5c" />
					<label for="example5c">Kiwi</label>
				</li>
				<li class="label-inline">
					<input type="checkbox" name="example5" value="4" id="example5d" />
					<label for="example5d">Other</label>
				</li>
			</ul>
		</fieldset>
Horizontal radio buttons in a <li> pattern with explicit labels (required)
View code
<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<fieldset class="chkbxrdio-grp">
			<legend class="required"><span class="field-name">Horizontal radio buttons in a <code>&lt;li&gt;</code> pattern with explicit labels</span> <strong class="required">(required)</strong></legend>
			<ul class="form-inline list-unstyled">
				<li class="label-inline">
					<input type="radio" name="example6" value="1" id="example6a" required="required" />
					<label for="example6a">Apple</label>
				</li>
				<li class="label-inline">
					<input type="radio" name="example6" value="2" id="example6b" />
					<label for="example6b">Orange</label>
				</li>
				<li class="label-inline">
					<input type="radio" name="example6" value="3" id="example6c" />
					<label for="example6c">Kiwi</label>
				</li>
				<li class="label-inline">
					<input type="radio" name="example6" value="4" id="example6d" />
					<label for="example6d">Other</label>
				</li>
			</ul>
		</fieldset>
Horizontal checkboxes in a <label> pattern with implicit labels (required)
View code
<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<fieldset class="form-inline chkbxrdio-grp">
			<legend class="required"><span class="field-name">Horizontal checkboxes in a <code>&lt;label></code> pattern with implicit labels</span> <strong class="required">(required)</strong></legend>
			<label for="example7a" class="checkbox-inline"><input type="checkbox" name="example7" value="1" id="example7a" required="required" />Smartphone</label>
			<label for="example7b" class="checkbox-inline"><input type="checkbox" name="example7" value="2" id="example7b" />Laptop</label>
			<label for="example7c" class="checkbox-inline"><input type="checkbox" name="example7" value="3" id="example7c" />Voice assistant</label>
			<label for="example7d" class="checkbox-inline"><input type="checkbox" name="example7" value="4" id="example7d" />Fusion reactor</label>
		</fieldset>
Horizontal radio buttons in a <label> pattern with implicit labels (required)
View code
<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<fieldset class="form-inline chkbxrdio-grp">
			<legend class="required"><span class="field-name">Horizontal radio buttons in a <code>&lt;label></code> pattern with implicit labels</span> <strong class="required">(required)</strong></legend>
			<label for="example8a" class="radio-inline"><input type="radio" name="example8" value="1" id="example8a" required="required" />Smartphone</label>
			<label for="example8b" class="radio-inline"><input type="radio" name="example8" value="2" id="example8b" />Laptop</label>
			<label for="example8c" class="radio-inline"><input type="radio" name="example8" value="3" id="example8c" />Voice assistant</label>
			<label for="example8d" class="radio-inline"><input type="radio" name="example8" value="4" id="example8d" />Fusion reactor</label>
		</fieldset>
Horizontal checkboxes in a <div> pattern with explicit labels (required)
View code
<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<fieldset class="form-inline chkbxrdio-grp">
			<legend class="required"><span class="field-name">Horizontal checkboxes in a <code>&lt;div&gt;</code> pattern with explicit labels</span> <strong class="required">(required)</strong></legend>
			<div class="label-inline">
				<input type="checkbox" name="example9" value="1" id="example9a" required="required" />
				<label for="example9a">Smartphone</label>
			</div>
			<div class="label-inline">
				<input type="checkbox" name="example9" value="2" id="example9b" />
				<label for="example9b">Laptop</label>
			</div>
			<div class="label-inline">
				<input type="checkbox" name="example9" value="3" id="example9c" />
				<label for="example9c">Voice assistant</label>
			</div>
			<div class="label-inline">
				<input type="checkbox" name="example9" value="4" id="example9d" />
				<label for="example9d">Fusion reactor</label>
			</div>
		</fieldset>
Horizontal radio buttons in a <div> pattern with explicit labels (required)
View code
<div class="wb-frmvld">
	<form action="#" method="get" id="validation-example">
		...
		<fieldset class="form-inline chkbxrdio-grp">
			<legend class="required"><span class="field-name">Horizontal radio buttons in a <code>&lt;div&gt;</code> pattern with explicit labels</span> <strong class="required">(required)</strong></legend>
			<div class="label-inline">
				<input type="radio" name="example10" value="1" id="example10a" required="required" />
				<label for="example10a">Smartphone</label>
			</div>
			<div class="label-inline">
				<input type="radio" name="example10" value="2" id="example10b" />
				<label for="example10b">Laptop</label>
			</div>
			<div class="label-inline">
				<input type="radio" name="example10" value="3" id="example10c" />
				<label for="example10c">Voice assistant</label>
			</div>
			<div class="label-inline">
				<input type="radio" name="example10" value="4" id="example10d" />
				<label for="example10d">Fusion reactor</label>
			</div>
		</fieldset>

Edge test cases

The following examples are only for testing purposes of some edge case configurations to ensure the plugin continues to work as expected.

<div> between the form and the form validation plugin

When there is a wrapper <div> on the <form> element between the form and the validation plugin.

Source code

<div class="wb-frmvld">
	<div id="app-root">
		<form action="#" method="get" id="edge-test-1">
			...
		</form>
	</div>
</div>
Date modified: