Giter Site home page Giter Site logo

formee's Introduction

formee
A tiny (532B) library for handling <form> elements

Features

  • Includes serialize and validation methods
  • Compatible with any UI library
  • Fully tree-shakeable

Additionally, this module is delivered as:

Install

$ npm install --save formee

Usage

๐Ÿ‘‹ View a full demo on CodePen

<form id="foo">
  <h2>Register</h2>
  <input type="email" name="email" />
  <input type="password" name="password" />
  <input type="password" name="confirm" />
  <button>Register</button>
</form>
const { validate } = require('formee');

const myForm = document.querySelector('#foo');
const myRules = {
  // RegExp rule
  email: /.+\@.+\..+/,
  // Function, with custom error messages
  password(val) {
    if (!val) return 'Required';
    return val.length >= 8 || 'Must be at least 8 characters';
  },
  // Function, comparing to other value
  confirm(val, data) {
    if (!val) return 'Required';
    return val === data.password || 'Must match your password';
  }
};

myForm.onsubmit = function (ev) {
  ev.preventDefault();
  let errors = validate(myForm, myRules);
  if (myForm.isValid) return alert('Success!');
  for (let k in errors) {
    // TODO: Render errors manually
    //   with {insert favorite UI lib here}
    console.log(`My rule & element's name: ${k}`);
    console.log('> Error message:', errors[k] || 'Required');
    console.log('> My form element(s):', myForm.elements[k]);
  }
};

API

formee.serialize(form)

Return: Object

Serializes a <form> into a data object.

Important: Any inputs that are unnamed, disabled, or are of type=file|reset|submit|button will be ignored.

form

Type: HTMLFormElement

The <form> element to evaluate.

formee.validate(form, rules, toCheck)

Return: Object

Validates a <form> according to its rules.
To check an individual input, you may pass its name as the toCheck value.

Important: The rules key names must match form.elements' names~!

Returns an Object of errors, whose keys are the failing rules keys (and the name=""s of failing elements) and whose values are your error messages (if provided) else false.

Additionally, the <form> and each of its elements will receive a new isValid property with a Boolean value.
For example:

let myForm = document.querySelector('#myform');
let errors = formee.validate(myForm, { ... });

if (!myForm.isValid) {
  let i=0, item;
  for (; i < myForm.elements; i++) {
    item = myForm.elements[i];
    console.log(`${item.name} โ€“ Am I valid?`, item.isValid);
    item.isValid || console.log('>> my error message:', errors[item.name]);
  }
}

form

Type: HTMLFormElement

The <form> element to validate.

rules

Type: Object

An object of rules for your form's inputs.

Important: The key names must match a <form> element's name="" attribute!

The form values will be serialized before reaching your rule(s). (see serialize)
For example, a select[multiple] may present its value as undefined, a String, or an Array of Strings.

Each rule:

  • May be a RegExp or a Function
  • Must return false or an error message (String) if invalid
  • Otherwise, must return true if valid

Your Function-type rules will receive the corresponding input's value and the entire data object.

validate(form, {
  password(val, data) {
    if (!val) return 'Required';
    if (val.length < 8) return 'Must be at least 8 characters';
    if (val !== data.confirmPassword) return 'Please confirm your password!';
    return true; // all good homie
  }
});

toCheck

Type: String
Default: undefined

If set, only the corresponding form element (with name={toCheck}) will be validated.
When unset (default), all form elements will be validated.

Important: The value must match a key within rules and a name="" attribute for one of <form>'s elements.

formee.bind(form, options)

Return: HTMLFormElement

Attaches serialize and validate methods to the <form> element.

Also registers a custom onsubmit handler that will:

  1. event.preventDefault the "submit" event
  2. Perform validate, then a) If all validation passed, call your options.onSubmit function b) Otherwise, call your options.onError function
let myForm = document.querySelector('#myform');

formee.bind(myForm, {
  rules: {
    // ...
  },
  onSubmit(ev) {
    // validation passed!
    console.log(ev.errors); //=> {}
    console.log(ev.target === myForm); //=> true
    console.log(myForm.isValid, myForm.errors); //=> true {}
  },
  onError(ev) {
    // validation failed!
    console.log(ev.errors); //=> { ... }
    console.log(ev.target === myForm); //=> true
    console.log(myForm.isValid, myForm.errors); //=> false { ... }
  }
});

// Now available:
// ---
form.serialize();
form.validate(/* specific item? */);

form

Type: HTMLFormElement

The <form> element to evaluate.

options.rules

Type: Object

Passed directly to validate โ€“ see rules.

options.onSubmit

Type: Function
Required: true

The callback to run when validation succeeds fails.

It receives the original event โ€“ however, a event.errors property is added, containing the output from validate.

options.onError

Type: Function
Required: true

The callback to run when validation fails.

It receives the original event โ€“ however, a event.errors property is added, containing the output from validate.

License

MIT ยฉ Luke Edwards

formee's People

Contributors

emiltholin avatar krismuniz avatar lukeed avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

formee's Issues

Nested keys example for Readme

To show usefulness of validating a single object with nested keys rather than lots of individual vars

<input type="text" name="address.town">
...
<input type="text" name="address.postalcode">

Then the rules:

getRules(){ 
   const result = { 
   ['address.town'](val) { 
   ... return valid
   }
  ['address.postalcode'](val) { 
   ... return valid
}

File Inputs

Currently file inputs are ignored โ€“ this was because handling File objects is usually very application-specific and validating them can be their own nightmare.

However, I've realized that the validation aspect is a moot point because you (the user) pass in your own validation rules, and formee will just respond to what your Functions & RegExps return values.

The only remaining "gotcha" is that the serialized return can no longer be passed directly into current fetch() requests if you have a File present. With the current formee version, tge data would just not include the file(s), making it safe for basic POST requests.

In order to upload files now, you have to manually check the DOM for values within your file inputs, and then upload them in a separate POST request or transform the current, single POST into a multipart request.

If formee were to serialize & validate file inputs, the only difference is that you'd have to check against the serialized data instead of adding to the serialized data. The cause for concern is that you may unknowingly attempt to send basic POST requests with multi-part bodies.

Either way, you have to formulate your outgoing HTTP request properly.


Edit: I should clarify that an object will still be returned, not a FormData instance.

Another (existing) shortcoming is that asynchronous validation methods won't be awaited. This is true for all validators currently, too, but may be highlighted with file validation.


What do you think? Should formee serialize & validate file inputs?


Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.