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

dry-forms

v1.0.2

Published

React form validation

Downloads

3

Readme

Dry Forms

DryForms is a form validation library for React.
DryForms is a lightweight, leaner and easy-to-use alternative to Formik library that gives you more freedom in how to validate input values in a HTML form. Though it is inspired by Formic, it takes a different, more functional approach to the process of verifying form field values.

Install

npm install -S dry-forms
yarn add dry-forms

Usage

Wrap your form into a function and pass that function into <Validate></Validate> component. Below is an example component that has a simple 'subscribe' form:

Example 1, basic validation

import React from "react"
import { Validate } from 'dry-forms'


const required = (s: string) => s.length>0
const isEmail = (s: string) => /^[\w.%+-]+@[\w-.]+\.[\w-]{2,}$/i.test(s)

const validators = {
  name: required,
  email: [required, isEmail]
}

const initials = {name: '', email: ''}

export default function Form1() {
  return <Validate validators={validators} values={initials}>
      {(values, errors, setVal, validate) => {

          const submit = () => {
              if (validate()) {
                  console.log('submit: ', values)
              }
          }

          return <form noValidate onSubmit={e => {e.preventDefault(); submit()}}>
              <input 
                  placeholder="Your name" 
                  value={values.name} 
                  onChange={e => setVal('name', e.target.value)}
                  className={errors.includes('name') ? 'error' : ''}
              />
              <input 
                  placeholder="E-mail"
                  value={values.email} 
                  onChange={e => setVal('email', e.target.value)}
                  className={errors.includes('email') ? 'error' : ''}
              />
              <input 
                  type='submit'
                  value="Submit"
              />
          </form>
      }}
  </Validate>
}

Each field in the form can have a single validator or an array of validators assigned to it in the validators array that you pass as a property to Validate component.
Validator - is just a function! In its simplest form it takes a value and returns true if the value is valid and false otherwise.
When you set a new value for the field (by calling setVal function in the onChange handler) DryForms calls every validator for that field starting from the first item in the array. If a validation function returns false, field's name is added to the errors array and rest of validators are not called.
Validate component also takes values property, that should have initial values for the form fields.

Example 2, messages

import React, { createRef } from "react"
import { Validators, required, isEmail, minLength, Validate } from 'dry-forms'


const notEmpty = required('Field is mandatory')

const validators: Validators = {
    email: [notEmpty, isEmail('You entered invalid email address')],
    password: [notEmpty, minLength(8, 'Use 8 or more characters')],
    confirm: [
        notEmpty,
        (value: string, all, submitting) => {
            if (!submitting) {
                return true
            }
            const valid = value === all.password
            return {valid, ...(!valid && {message: 'Passwords do not match'})}
        }
    ]
}

const initials = {email: '', password: '', confirm: ''}

export default function Form2() {
    const formRef = createRef<HTMLFormElement>()

    return <Validate validators={validators} values={initials} form={formRef}>
        {(values, errors, setVal, validate, messages) => {

            const submit = () => {
                if (validate()) {
                    console.log('submit: ', values)
                }
            }

            return <form ref={formRef} noValidate onSubmit={e => {e.preventDefault(); submit()}}>
                <input 
                    name="email" 
                    placeholder="E-mail"
                    value={values.email} 
                    onChange={e => setVal('email', e.target.value)}
                    className={errors.includes('email') ? 'error' : ''}
                />
                {'email' in messages && messages.email.map((m,i) => <span key={i}>{m}</span>)}
                <input 
                    type='password'
                    name="password" 
                    placeholder="Password, use 8 or more characters"
                    value={values.password} 
                    onChange={e => setVal('password', e.target.value)}
                    className={errors.includes('password') ? 'error' : ''}
                />
                {'password' in messages && messages.password.map(m => <span key={m}>{m}</span>)}
                <input 
                    type='password'
                    name="confirm" 
                    placeholder="Confirm password"
                    value={values.confirm} 
                    onChange={e => setVal('confirm', e.target.value)}
                    className={errors.includes('confirm') ? 'error' : ''}
                />
                {'confirm' in messages && messages.confirm.map(m => <span key={m}>{m}</span>)}
                <input 
                    type='submit'
                    value="Submit"
                />
            </form>
        }}
    </Validate>
}

API Reference

Validate component

<Validate validators=...  values=... form=...>
</Validate>

validators: Record<string, Validator|Validator[]>

  type Validator = (value: any, all: Record<string, any>, sibmitting: boolean) => boolean|ValidationResult
  interface ValidationResult {
    valid: boolean
    value?: any
    message?: string
  }
  • value - a new value to validate
  • all - read-only collection of all values
  • sibmitting - whether it was called in the process of 'final' validation (e.g. in onSubmit handler), validate() sets this to true

values: Record<string, any>

initial fields' values

form: React.RefObject< HTMLElement >

optional reference to the HTML form element. If passed, first input element with invalid value will receive focus after calling validate()

Validate child/render function

<Validate >
{
  (values, errors, setVal, validate) => { /* ... */ }
}
</Validate>

values: Record<string, any>

Current field values.

errors: string[]

Array of failed field names.

setVal: (name: string, value: any, validate?: boolean = true, submitting?: boolean = false, focus?: boolean = false) => boolean

Function that sets the value for a field and optionally runs validation.

  • name - field's name
  • value - new field value
  • validate - true to set a new value and validate it or false to update a value without validation
  • submitting - if it was called in validate() presumably during submitting process
  • focus - true to try to set focus on input element

validate: (dryRun?: boolean = false) => boolean

Validate all fields, returns true if all values were sucessfully validated. The best place to call it in your onSubmit handler, e.g.

onSubmit() {
  if (validate()) {
     // values are valid, it is OK to call fetch(...) etc.
  }
}
  • dryRun - do validation in a stealthy way, i.e. without adding errors and messages
...
<input 
  type='submit'
  value="Submit"
  disabled={!validate(true)} // <- check if valid but don't tell user about errors
/>