jaywcjlove / validator.js

:interrobang: Lightweight JavaScript form validation, that had minimal configuration and felt natural to use. No dependencies, support UMD.
https://git.io/validatorjs
551 stars 118 forks source link
assert form form-validation javascript sanitize validate validation validator validatorjs

validator.js

Buy me a coffee Build & Deploy No Dependencies npm bundle size npm version Coverage Status

Lightweight JavaScript form validation, that had minimal configuration and felt natural to use. No dependencies, support UMD.

⚠️ The v1 version document preview is here.

Install · Usage · React · Hook · React Native · Form · API · npm · License

Used in the browser client

Refer to the validator.min.js file in the application, manually download and link validator.min.js in HTML.

<script type="text/javascript" src="https://github.com/jaywcjlove/validator.js/raw/master/dist/validator.min.js"></script>

It can also be downloaded via UNPKG:

CDN: UNPKG | jsDelivr | Githack | Statically | bundle.run

Open in CodeSandbox

<form id="form">
  <div>
    <label for="email">EMail:</label>
    <input type="email" name="email" placeholder="" />
  </div>
  <div>
    <label for="password">Password:</label>
    <input type="password" name="password" />
  </div>
  <div>
    <label for="repassword">Confirm Password:</label>
    <input type="repassword" name="repassword" />
  </div>
  <div>
    <button type="submit">Submit</button>
    <button type="reset">Reset</button>
  </div>
</form>
<script type="text/javascript" src="https://unpkg.com/validator.tool/dist/validator.min.js"></script>
<script type="text/javascript">
var validator = new Validator({
  form: document.getElementById('form'),
  rules: {
    email: {
      validate: (val) => val ? '' : 'Required!',
    },
    password: {
      // validate: (val) => val < 5 || val > 15 ? '字数大于5,小于15' : ''
    },
    repassword: {
      validate: (val) => !val ? 'Required!' : '',
    },
  }
});

validator.form.onsubmit = (evn) => {
  evn.preventDefault();
  const values = validator.getValues();
  console.log(values);
}

validator.form.onreset = (evn) => {
  const data = validator.reset();
  console.log(data);
}
</script>

Install

$ npm install validator.tool --save
# Or
$ npm install @validator.tool/hook --save

Usage

import { useState, useRef } from 'react';
import Validator from 'validator.tool';

function Example() {
  const [data, setData] = useState({
    email: 'kennyiseeyou@gmail.com'
  });
  const validator = useRef(
    new Validator({
      initValues: { ...data },
    })
  );
  return (
    <form>
      <div>
        <label htmlFor="email">EMail:</label>
        <input type="email" name="email" defaultValue={data.email} />
        <span>
          {validator.current.message('email', data.email, {
            validate: (val) => !/^[A-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(val) ? `The ${val} must be a valid email address.` : ''
          })}
        </span>
      </div>
      <button type="submit">Submit</button>
      <button type="reset">Reset</button>
    </form>
  );
}
import { useState } from 'react';
import { useValidator } from '@validator.tool/hook';

function Example() {
  const [data, setData] = useState({
    email: 'kennyiseeyou@gmail.com'
  });
  const { validator } = useValidator({
    initValues: { ...data },
  });
  return (
    <form onSubmit={...} onReset={...} onChange={...} onBlur={...}>
      <div>
        <label htmlFor="email">EMail:</label>
        <input type="email" name="email" defaultValue={data.email} />
        <span>
          {validator.message('email', data.email, {
            validate: (val) => !/^[A-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(val) ? `The ${val} must be a valid email address.` : ''
          })}
        </span>
      </div>
      <button type="submit">Submit</button>
      <button type="reset">Reset</button>
    </form>
  );
}

Used in the React App

Open in CodeSandbox

import { useRef, useState } from 'react';
import { useValidator } from '@validator.tool/hook';

function Demo() {
  const [data, setData] = useState({
    email: 'kennyiseeyou@gmail.com'
  });
  const { validator, handleReset, handleSubmit } = useValidator({
    initValues: data,
    validate: (value, values, field) => {
      if (field === 'password' && !value) {
        return 'Required!';
      }
    }
  });

  const onSubmit = (value: Values) => {
    console.log('value', value)
  }
  const onReset = (value: Values) => {
    setData({ ...value });
  }

  function handleChange(env) {
    const target = env.target;
    const value = target.type === "checkbox" ? target.checked : target.value;
    const name = target.name;
    setData({ ...data, [name]: value });
  }

  return (
    <form
      onSubmit={handleSubmit(onSubmit)}
      onReset={handleReset(onReset)}
      onChange={handleChange}
      onBlur={handleChange}
      // onInput={handleChange}
    >
      <div>
        <label htmlFor="email">EMail:</label>
        <input type="email" name="email" defaultValue={data.email} />
        <span>
          {validator.message('email', data.email, {
            validate: (val) => !/^[A-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(val) ? `The ${val} must be a valid email address.` : ''
          })}
        </span>
      </div>
      <div>
        <label htmlFor="password">Password:</label>
        <input type="password" name="password" />
        <span>{validator.message('password', data.password)}</span>
      </div>
      <div>
        <button type="submit">Submit</button>
        <button type="reset">Reset</button>
      </div>
    </form>
  );
}

Support React Hook

npm bundle size npm version Open in CodeSandbox

import { useValidator } from '@validator.tool/hook';

const { validator, forceUpdate } = useValidator({});

Used in the React Native App

You need to wrap validator with <Text> Element.

import React, { useRef } from 'react';
import { Text, View, Button } from 'react-native';
import { useValidator } from '@validator.tool/hook';

const WelcomeScreen = () => {
  const [text, onChangeText] = React.useState('Useless Text');
  const { validator, forceUpdate } = useValidator({
    initValues: { text },
    validate: (value = '', values, field) => {
      if (field === 'username' && value.length > 3) {
        return '!! username > 3';
      }
    },
  });
  return (
    <View>
      <TextInput onChangeText={onChangeText} value={text} />
      <Text>
        {validator.message('username', text)}
      </Text>
      <Button
        onPress={() => {
          validator.showMessages();
          forceUpdate();
        }}
        title="Submit"
        color="#841584"
      />
    </View>
  );
};

API

export declare type Value = (number | FormDataEntryValue)[] | number | boolean | null | FormDataEntryValue;
export declare type Values = Partial<Record<string, Value>>;
export declare type Fields = Partial<Record<string, boolean>>;
export declare type Rules = Partial<Record<string, RulesOption>>;
export interface RulesOption {
  /** Validate the form's values with function. */
  validate?(value?: Value, values?: Validator['values'], field?: string): string;
}
export declare type ValidatorOption = {
  messagesShown?: boolean;
  rules?: Rules;
  initValues?: Values;
  form?: HTMLFormElement | null;
  validate?: RulesOption['validate'];
};
export default class Validator {
  constructor(options?: ValidatorOption);
  validate?: RulesOption['validate'];
  form?: HTMLFormElement | null;
  fields: Fields;
  rules: Rules;
  values: Values;
  initValues?: Values;
  set resetInitValue(val: Values);
  messagesShown: boolean;
  errorMessages: Partial<Record<string, string>>;
  showMessages: () => boolean;
  hideMessages: () => boolean;
  getForm: () => HTMLFormElement | null | undefined;
  setForm: (form: HTMLFormElement) => void;
  /** How you define validation rules and add messages into the form. */
  message: (field: string, inputValue?: Value | undefined, options?: RulesOption | undefined) => string | undefined;
  setValues: (values?: Values) => void;
  getValues: () => Values;
  reset: () => Values;
  fieldValid: (field: string) => boolean;
  /**
   * Returns a boolean if all the fields pass validation or not.
   * @returns Boolean
   */
  allValid(): boolean;
}

Use with third-party packages

validator.js

npm bundle size

String validation

import isEmail from 'validator/es/lib/isEmail';

function Demo() {
  return (
    <p>
      {validator.current.message('email', data.email, {
        validate: (val) => !isEmail(val) ? `The ${val} must be a valid email address.` : ''
      })}
    </p>
  );
}

Zod

TypeScript-first schema validation with static type inference

npm bundle size

Development

To develop, Install dependencies, Get the code:

$ git https://github.com/jaywcjlove/validator.js.git
$ cd validator.js     # Into the directory
$ npm install         # or  yarn install
$ npm install --workspaces  # Install monorepo dependency

To develop, run the self-reloading build:

$ npm run lib:watch   # Monitor the compiled package `validator.tool`
$ npm run hook:watch  # Monitor the compiled package `@validator.tool/hook`

Run Document Website Environment.

$ npm run start

To contribute, please fork Hotkeys.js, add your patch and tests for it (in the <rootDir>/packages/**/__tests__/*.{js,jsx,ts,tsx} folder) and submit a pull request.

$ npm run coverage
$ npm run test # Development model

Related

Contributors

As always, thanks to our amazing contributors!

Made with github-action-contributors.

License

Licensed under the MIT License.