npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@pageclip/valid-form

v1.1.1

Published

HTML5 form validation helpers

Downloads

1,159

Readme

ValidForm

ValidForm is a thin JavaScript wrapper on the HTML5 Form Validation features. It is very small at about 200 lines of code (7k, 5.6k compressed), and it has no dependencies. Nope, none.

For background, check out the blog post that lead to this module.

The HTML5 form validation features are pretty good, but have a couple warts. ValidForm is a layer on the HTML5 features and attempts to augment them with three things:

  1. An invalid class on inputs when they are invalid. This class provides better user feedback than the :input pseudo selector.
  2. Support for displaying custom messages by way of HTML attributes or an object on initialization.
  3. Validation error messages are displayed in a custom div.

What does it look like (with custom styles)?

Try it out →

Installing

Without npm / yarn

If you just want to include a script in an HTML file, you can find the valid-form.js and valid-form.min.js in the dist folder.

There will be a ValidForm global.

So you can call ValidForm(formElement, options). Other functions exposed will be properties on ValidForm. For example, ValidForm.handleCustomMessageDisplay(input, options)

And usage:

<script>
  var formElement = document.querySelector('form')
  ValidForm(formElement)
</script>

With npm / yarn / webpack

npm install @pageclip/valid-form
# or
yarn add @pageclip/valid-form

(Apologies for the scoped package. NPM is annoying)

Then import it like so:

import ValidForm from '@pageclip/valid-form'
const formElement = document.querySelector('form')
ValidForm(formElement)

Or import the other exposed functions if you want to:

import {
  toggleInvalidClass,
  handleCustomMessages,
  handleCustomMessageDisplay
} from '@pageclip/valid-form'

Usage

For the tl;dr, check out the example code, and see it in action.

The main function is ValidForm() which you call with a <form> element.

const formElement = document.querySelector('form')
ValidForm(formElement, options) // options optional

It will hook the invalid and input events for <input>, <select>, and <textarea> elements.

You can use any HTML5 validation attributes on these inputs and ValidForm will display the same things you would get with raw HTML5 form validation. e.g. required, pattern, type, etc.

<form method="post" action="/">
  <div class="form-group">
    <input required type="email" pattern="[ab]+@.+" />
  </div>

  <div class="form-group">
    <select required>
      <option value="">pick one!</option>
      <option value="cat">Cat</option>
      <option value="dog">Dog</option>
      <option value="catdog">Catdog</option>
    </select>
  </div>

  <div class="form-group">
    <textarea required pattern="[ab ]+"></textarea>
  </div>
</form>

CSS styles are not provided by ValidForm, so you will need to do your thing. Fortunately, the amount of CSS required is small.

As an example, if you are using bootstrap and all the ValidForm defaults, here is how to recreate the example in the image at the top of this readme.

/*
  Style the input itself when it is invalid
*/
.form-control.invalid {
  border-color: red;
}

/*
  Style the validation errors.

  By default, `ValidForm` inserts the `.validation-error` div
  _before_ the input. So we abs position in the top right.

  Why insert before? It is nicer on the user than inserting
  after the input and moving elements down the page.
*/
.form-group {
  position: relative;
}
.form-group .validation-error {
  position: absolute;
  right: 0;
  top: 1px;

  color: red;
  font-size: 14px;
}

The invalid Class

The :invalid pseudo selector built into the browser isn't very good. If your input is required and empty on page load, :invalid is true. If you style :invalid with, say, a red border, all required fields will be red on page load. Kinda dumb.

The invalid class is added only after the user submits the form, then stays until the user fixes the input. An example of what it will generate:

<form method="post" action="/">
  <div class="form-group">
    <!-- invalid class added by ValidForm -->
    <input required class="invalid" type="email" pattern="[ab]+@.+" />
  </div>
</form>

And you can style it like so

.invalid {
  border-color: red;
}

The class name is configurable in options.

Custom Messages

Custom messages can be specified in 2 ways:

  1. As attributes on the input
  2. In a customMessages object on the options to ValidForm()

Naming of these is based on the ValidityState object provided by the browser. For attributes, prepend a data-, for the options object use them as is.

Specifying as attributes:

  <form method="post" action="/">
    <input
      required
      type="email"
      pattern="[ab]+@.+"
      data-valueMissing="Enter something, plz"
      data-patternMismatch="Just give me a's and b's"
      data-rangeOverflow="Number too low!"
      data-rangeUnderflow="Number too high!"
      data-stepMismatch="Step doesn't fit into my notches!"
      data-tooLong="Text is too long"
      data-tooShort="Text is too short"
      data-typeMismatch="Hey, this isn't an email"
      data-badInput="Something bad happened"
      />
    </form>

Specifying as an object:

const formElement = document.querySelector('form')
ValidForm(formElement, {
  customMessages: {
    valueMissing: "Enter something, plz",
    patternMismatch: "Just give me a's and b's",
    rangeOverflow: "Number too low!",
    rangeUnderflow: "Number too high!",
    stepMismatch: "Step doesn't fit into my notches!",
    tooLong: "Text is too long",
    tooShort: "Text is too short",
    typeMismatch: "Hey, this isn't the correct type",
    badInput: "Something bad happened"

    // Special mismatches for different input types: `${type}Mismatch`
    emailMismatch: "Hey, this isn't an email",
    urlMismatch: "Not a URL :(",
    numberMismatch: "Nope, not a number!",
  }
})

Attributes take precedence over the object. So you can provide blanket custom messages with the customMessages object, then override with any input specific messages as attributes on the input.

Custom Message Display

When there is an invalid input, ValidForm will do 2 things:

  1. Insert a message <div class="validation-error" /> either before (default) or after the input. Placement and classname are configurable.
  2. Add a class (has-validation-error is default) to the input's parent element.

When the user fixes the error, the message div and the parent class will be removed.

An example of the markup when there is an error:

<form method="post" action="/">
  <div class="form-group has-validation-error">
    <div class="validation-error">Oops, there was an error!</div>
    <input required class="invalid" type="email" pattern="[ab]+@.+" />
  </div>
</form>

API

ValidForm(element, options)

The main function, and the one you should probably use. e.g.

const formElement = document.querySelector('form')
ValidForm(formElement, {
  invalidClass: 'form-input_invalid',
  errorPlacement: 'after',
  customMessages: {
    valueMissing: 'Enter something tho.'
  }
})
  • element - Can be a <form>, <input>, <select>, or <textarea> element. It will throw an error if anything else. When it is a form, it will properly focus the first invalid input on submission.
  • options - (optional) Object
    • invalidClass - (default: 'invalid') Class applied to input when invalid
    • validationErrorClass - (default: 'validation-error') Class applied to error message <div> when there is a validation error,
    • validationErrorParentClass - (default: 'has-validation-error') Class applied to ,
    • errorPlacement - (default: 'before') Where to insert the error message node. It can be 'before' or 'after'
    • customMessages - (default: {}) See custom messages section. When nothing is specified, and for any non-specified message, the browser-default messages will be shown.

ValidForm() calls all the following functions. If you want super custom behavior, you can use the following 3 functions.

toggleInvalidClass(input, invalidClass)

Hooks the input and invalid events on an input.

  • input - A <input>, <select>, or <textarea> element.
  • invalidClass - String class to be applied to input when invalid

handleCustomMessages(input, customMessages)

Deals with showing custom messages.

  • input - A <input>, <select>, or <textarea> element.
  • customMessages - (default: {}) See custom messages section. When nothing is specified, and for any non-specified message, the browser-default messages will be shown.

handleCustomMessageDisplay(input, options)

Shows validation messages in a custom div when there is a validation error.

  • input - A <input>, <select>, or <textarea> element.
  • options - (optional) Object
    • validationErrorClass - (default: 'validation-error') Class applied to error message <div> when there is a validation error,
    • validationErrorParentClass - (default: 'has-validation-error') Class applied to ,
    • errorPlacement - (default: 'before') Where to insert the error message node. It can be 'before' or 'after'

Developing

Write code in src, yo.

yarn install
yarn build # build all the js
yarn site  # run the example site

The site is available at http://localhost:8080.

License

MIT