Skip to content

Latest commit

 

History

History
337 lines (247 loc) · 9.34 KB

API.md

File metadata and controls

337 lines (247 loc) · 9.34 KB

API

Revalidation(Component)

Creates an enhanced React Component containing validation and state keeping capabilities.

Arguments

  1. Component (React Component): The React Component that will be enhanced with validation and state keeping functionality.

Returns

<HigherOrderComponentForm />

Higher Order React Component: The provided component will be enhanced with a revalidation prop.

Props

  • initialState (Object):

    The initial state, make sure to provide defaults for all form fields.

  • rules (Object):

    An object of rules, consisting of arrays containing predicate function / error message tuple, f.e. {name: [[a => a.length > 2, 'Minimum length 3.']]}

  • validateSingle (Boolean):

    if you need validation per field you can set the option to true (default is false).

  • validateOnChange: (Boolean|Function):

    if you need instant validation as soon as props have changed set to true (default is false). Pass in a function to enable dynamic validation after the form has been submitted:

    <Form validateOnChange={(submitted) => submitted} />

    The provided function will receive the current state, enabling to set validateOnChange depending on that state.

  • asyncErrors (Object):

    An object containing asynchronous errors, f.e. {userName: ['UserName is not available.']} Enables to pass any asynchronous errors back into Revalidation.

  • updateForm (Object):

    Overrides the current form values. Only use in situations where setState isn't enough, add and remove the updateForm before and after updating the form values to avoid destroying the local component state when the component will receive new props. To initialize the state use initialState. updateForm is ignored when the Component is initially mounted.

Example

import React from 'react'
import Revalidation, { isValid } from 'revalidation'
import { head } from 'ramda'

import helpers from './helpers'

const {
  isNotEmpty,
  isLengthGreaterThan,
  hasCapitalLetter,
} = helpers

const displayErrors = (errorMsgs) =>
  isValid(errorMsgs) ? null : <div className='error'>{head(errorMsgs)}</div>

const getValue = e => e.target.value

const Form = ({ revalidation : {form, validate, valid, errors = {}, onSubmit}, onSubmitCb }) =>
  (
    <div className='form'>
      <div className='formGroup'>
        <label>Name</label>
        <input
          type='text'
          value={form.name}
          onChange={e => validate('name', getValue(e))}
        />
        { errors.name }
      </div>
      <div className='formGroup'>
        <label>Random</label>
        <input
          type='text'
          value={form.random}
          onChange={e => (validate('random', getValue(e))}
        />
        { displayErrors(errors.random) }
      </div>
      <button onClick={() => onSubmit(onSubmitCb)}>Submit</button>
    </div>
  )

const EnhancedForm = Revalidation(Form)

// ...usage

const initialState = {name: '', random: ''}

const validationRules = {
  name: [
    [isNotEmpty, 'Name should not be  empty.']
  ],
  random: [
    [isLengthGreaterThan(7), 'Minimum Random length of 8 is required.'],
    [hasCapitalLetter, 'Random should contain at least one uppercase letter.'],
  ]
}


<EnhancedForm
    initialState={initialState}
    rules={validationRules}
    validateSingle
    validateOnChange
/>

revalidation

An additional prop revalidation is provided to the enhanced component.

The following properties are provided by revalidation.

  • form (Object):

    Containing the current form values. f.e. input field name can be accessed via form.name

        const Form = ({ revalidation : {form, onSubmit }, onSubmitCb) =>
          (
            <div className='form'>
              <div className='formGroup'>
                <label>Name</label>
                <input
                  type='text'
                  value={form.name}
                />
              </div>
              <button onClick={() => onSubmit(onSubmitCb)}>Submit</button>
            </div>
          )
  • valid (Boolean):

    A computed validation state. Useful when initializing the form and needing to disable a submit f.e.

    <button {...{disabled : !valid}} onClick={() => submit()}>Submit</button>
  • submitted (Boolean):

    Set to true after the form has been submitted.

  • onChange(key, value, [type], [callback]) (Function):

    Apply any changes to a field value and validate.

    <input
        type='text'
        value={form.name}
        onChange={e => onChange('name', e.targetValue)}
    />

    Additionally one can pass in a callback function.

    <input
        type='text'
        value={form.name}
        onChange={e => onChange('name', e.targetValue, null, ({valid, form}) => valid ? submitCb(form) : null )}
    />
  • updateState(form) (Function):

    Udpate the complete form state, f.e. implementing a clear function.

     <button onClick={() => updateState({ name: '', random: '' })}>Reset</button>
  • onSubmit([cb]) (Function):

    Function for validating all fields. For example when submitting a form. To enable an action after successful validation, provide a callback. Thee current state (including errors) as well as the calculated valid state will be passed to the provided callback function.

    <button onClick={() => onSubmit(({valid, form}) => valid ? onSubmitCb(form): doSomethingElse())}>Submit</button>
  • errors (Object):

    The object containing the errors. How to display the errors isn't up to Revalidation.

    Initially errors might be an empty object, this is the case when no validation has run.

    Every field is mapped to list of error messages.

    {
      name: [],
      random: ['Minimum Random length of 8 is required.']
    }
    

    Display the error messages as needed. This approach enables to define field specific error messages if needed.

    const displayErrors = (errorMsgs) =>
      isValid(errorMsgs) ? null : <div className='error'>{head(errorMsgs)}</div>
    
     <div className='formGroup'>
      <label>Random</label>
      <input
        type='text'
        value={form.random}
        onChange={e => (onChange('random', getValue(e))}
      />
      { displayErrors(errors.random) }
    </div>
  • updateErrors(Function): Enables to update any errors.

  • updateAsyncErrors(Function): Enables to update any asynchronous errors. Useful when working with asynchronous validations. Pass the updateAsyncErrors to a callback, once the validation is finished set the result manually.

    <button
      onClick={() => onSubmit(({form, valid}) => valid ? submitCb(form, updateAsyncErrors) : console.log('something went wrong!'))}>Submit
    </button>
    
    // use in another Component...
    class HigherUpComponent extends React.Component {
      onSubmit = (formValues, updateAsyncErrors) => {
        setTimeout(() => {
          // something went wrong...
          updateAsyncErrors({ name: ['Username is not available'] })
        }, 1000)
      }
    
      render() {
        {/* ... */}
      }
    }
  • settings (Object): Access the current settings: { validateOnChange: true, validateSingle: true }

Additionally revalidation offers a number of helper functions to quickly update any values or validations.

  • debounce (Function): A helper function for triggering asynchronous validations. The passed in asynchronous validation can be debounced by a specified time. i.e. 1000 ms.

    <input
      type="text"
      value={form.name}
      onChange={debounce.name(usernameExists, 1000)}
    />
  • updateValue (Function): Update a specific field value. Important to note that no validation will run. Use updateValueAndValidate if you need to update and validate of field. A name attribute must be defined on the element for updateValue to update the value.

      <input
        type='text'
        className={isValid(errors.random) ? '' : 'error'}
        name='random'
        value={form.random}
        onChange={updateValue}
      />
  • validateValue (Function): Validates a specific field. Useful when validation should happen after an onBlur i.e. A name attribute must be defined on the element for validateValue to validate the value.

      <input
        type='text'
        className={isValid(errors.random) ? '' : 'error'}
        name='random'
        onBlur={validateValue}
        value={form.random}
        onChange={updateValue}
      />
  • updateValueAndValidate (Function): Updates and validates the value for the specified element. A name attribute must be defined on the element for updateValueAndValidate to update the value.

      <input
        type='text'
        className={isValid(errors.random) ? '' : 'error'}
        name='random'
        onBlur={validateValue}
        value={form.random}
        onChange={updateValue}
      />

===

Helpers

isValid

Use isValid to check if errors exist for an input.

<input
  type='text'
  className={isValid(errors.name) ? '' : 'error'}
  value={form.name}
  onChange={compose(onChange('name'), getValue)}
/>