Skip to main content Accessibility Feedback
Skip to Documentation Content

Form Validation

New! This component was just added to Kelp. Enjoy!

Progressively enhance the browser-native constraint validation API on any <form> element.

  • Validate fields on blur.
  • Re-validate invalid field as the user types.
  • Validate all fields on submit, and shifts .focus() to the first invalid field.
  • Create custom error messages.
  • Add <fieldset> validation, requiring at least one radio or checkbox to be :checked.
  • Prevent form submissions if the form is invalid.

Usage

Wrap any form in the <kelp-form-validate> element.

<kelp-form-validate>
	<form action="/" method="get">
		<!-- ... -->
	</form>
</kelp-form-validate>

Then, use any constraint validation attributes on your form fields to provide validation criteria.

<!-- Make a field required -->
<label for="username">Username</label>
<input type="text" name="username" id="username" required>

<!-- Require the input to be a valid email format -->
<label for="email">Email *</label>
<input type="email" name="email" id="email" required>

<!-- 
	Match a specific pattern 
	(in this example, exactly 5 digits)
-->
<label for="code">Auth Code (5-digits)</label>
<input
	type="text"
	name="code"
	id="code"
	pattern="[0-9]{5}"
	required
>

Custom Error Messages

By default, the <kelp-form-validate> component will use the browser’s native error message.

You can use the [validate-msg] attribute to override that native message with a custom one.

<label for="email">Email *</label>
<input 
	type="email" 
	name="email" 
	id="email" 
	required
	validate-msg="Please use a valid email."
>

Group Validation

To require that at least one checkbox or radio button in a group is selected, add the [validate-group] attribute to the parent <fieldset> element.

<fieldset validate-group>
	<legend>What's your favorite Pixar movie?</legend>

	<label for="up">
		<input type="radio" id="up" name="movie" value="up">
		Up!
	</label>
	<label for="wall-e">
		<input type="radio" id="wall-e" name="movie" value="wall-e">
		WALL-E
	</label>
	<label for="toy-story">
		<input type="radio" id="toy-story" name="movie" value="toy-story">
		Toy Story
	</label>
</fieldset>

Error Color

Form fields with errors use the --color-invalid CSS variable for their border and focus color. Error messages use the --color-danger-out CSS variable.

@layer kelp.theme {
	:root,
	.light {
		--color-invalid: var(--color-red-50);
		--color-danger-outline: var(--color-red-50);
	}

	.dark {
		--color-invalid: var(--color-red-60);
		--color-danger-outline: var(--color-red-70);
	}
}

Events

The <kelp-form-validate> element emits a few events.

  • kelp-form-validate:ready emits when the component is instantiated.
  • kelp-form-validate:success emits when the form passes validation.
  • kelp-form-validate:failed emits when the form fails validation.

The event.detail object contains the .form element that was validated.

document.addEventListener('kelp-form-validate:ready', (event) => {
	console.log('ready:', event.target);
});

document.addEventListener('kelp-form-validate:success', (event) => {
	console.log('The form was successfully validated', event.detail.form);
});

document.addEventListener('kelp-form-validate:failed', (event) => {
	console.log('The form failed validation', event.detail.form);
});

Methods

While web components are self-instantiating, the <kelp-form-validate> element has a method you can manually run if needed.

  • .init() - Manually initialize the component, if it fails for some reason.
const validate = document.querySelector('kelp-form-validate');
validate.init();

Demo

Edit a field with invalid information, then click on another field to try the real-time validation. Or submit the form with invalid data to see whole-form validation.

What's your favorite Pixar movie?
What are your favorite Pixar movies?