autovalid

Automatically adds/removes `.invalid` classes from form elements according to current state of HTML5 validation

Usage no npm install needed!

<script type="module">
  import autovalid from 'https://cdn.skypack.dev/autovalid';
</script>

README

WHAT IT DOES

Automatically adds and removes CSS class .invalid depending on the current status of HTML validation. If any form element becomes invalid, an .invalid class will be added to that element and also to it's parent <label> tag (if present) as well as to the form itself.

HOW TO USE

Just import the autovalid function and call it after the DOM is loaded (for example, inside an onMount() block in Svelte). By default, it will watch the whole DOM. If any elements fail because of HTML5 validation (for example if you've added a required attribute and the field is empty), then the .invalid CSS class will be added to affected elements as described above.

WHY NOT JUST USE :invalid?

HTML5 validation is cool. Want a field to be required? Just add a required attribute to the tag. Wanna loosely validate an email address? Just make the input type="email". If a field is invalid, the element gets a pseudo-selector of :invalid which you can use to style the field (for example by giving it a red border). And this is where the trouble begins 😱. For one thing, your form will probably start out invalid by default. Duh. So, the way this standard has been implemented, using :invalid to style things is basically a non-starter.

Instead, we'll add an event listener to add a class of .invalid when an element becomes invalid – which happens on attempted form submission. Then we'll remove that class whenever the field is updated and the field is valid.

WRAPPING LABEL TAG

If you wrap your input in a <label> tag in order to associate the input with the parent label, then the wrapping label will also have the class .invalid added and removed. This makes it possible to even do things like have a custom error message which is hidden until the parent label gets the .invalid class.

FORM TAG

If any elements within the form are invalid, then the <form> tag itself will also receive an .invalid class. This makes it possible to display a generic message like "Please correct the above errors" using CSS only. For example:

<style>
  form .invalid-message {
    display: none;
  }
  form.invalid .invalid-message {
    display: block;
    color: red;
  }
</style>

<form>
  ...
  <h2 class="invalid-message">Please correct the above errors.</h2>
</form>

ALL TOGETHER NOW

It's actually a lot simpler than it sounds. This is all it does:

  1. Calling this function will add listeners to all form inputs, selects, and textareas.
  2. When a form field becomes invalid according to HTML5 validation:
  • .invalid class is added to the form field element itself
  • .invalid class is also added to the parent <label> tag if present
  • .invalid class is also added to the parent <form> tag
  1. When a form field becomes valid again:
  • .invalid class is removed from the form field element
  • .invalid class is removed from the parent <label> tag if present
  • .invalid class is removed from the parent <form> tag if there are no invalid fields remaining in this form

...and that's it. It just adds and removes the .invalid class so you can style stuff with CSS depending on the current state of HTML5 validation.

OPTIONS

You can pass an options object in to tweak some options.

  • scope: <DOM Element> - Limit the scope to everything under a given element instead of watching the whole DOM.
  • preventDefault: <Boolean>: Don't show the browser default message popups (useful if you're adding your own custom ones).
Example with options:
autovalid({
  scope: myFormElement,
  preventDefault: true
});

BASIC EXAMPLE

<script>
  import { onMount } from 'svelte';
  import autovalid from 'autovalid';

  onMount(() => {
    autovalid();
  });
</script>

<style>
  input.invalid {
    border: 2px solid red;
  }
</style>

<form>
  <label>
    Full Name
    <input type="text" name="fullName" required />
  </label>
</form>