Skip to content

Instantly share code, notes, and snippets.

@JakeLaCombe
Last active November 28, 2017 19:43
Show Gist options
  • Save JakeLaCombe/f11bd3ed998cd890ab9c065606c59a4f to your computer and use it in GitHub Desktop.
Save JakeLaCombe/f11bd3ed998cd890ab9c065606c59a4f to your computer and use it in GitHub Desktop.

Validators

import validator from 'validator';
const required = (value) => {
  if (!value.toString().trim().length) {
    // We can return string or jsx as the 'error' prop for the validated Component
    return 'require';
  }
};

const email = (value) => {
  if (!validator.isEmail(value)) {
    return `${value} is not a valid email.`
  }
};

const lt = (value, props) => {
  // get the maxLength from component's props
  if (value.toString().trim().length > props.maxLength) {
    // Return jsx
    return <span className="error">The value exceeded {props.maxLength} symbols.</span>
  }
};

const password = (value, props, components) => {
  // NOTE: Tricky place. The 'value' argument is always current component's value.
  // So in case we're 'changing' let's say 'password' component - we'll compare it's value with 'confirm' value.
  // But if we're changing 'confirm' component - the condition will always be true
  // If we need to always compare own values - replace 'value' with components.password[0].value and make some magic with error rendering.
  if (value !== components['confirm'][0].value) { // components['password'][0].value !== components['confirm'][0].value
    // 'confirm' - name of input
    // components['confirm'] - array of same-name components because of checkboxes and radios
    return <span className="error">Passwords are not equal.</span>
  }
};

Implemenation of Validation

import Form from 'react-validation/build/form';
import Input from 'react-validation/build/input';
import React, { Component } from 'react';

export default class Login extends Component {
    handleSubmit = (event) => {
        event.preventDefault();

        // Emulate async API call
        setTimeout(() => {
            this.form.showError(this.userInput, <span>API error</span>);
        }, 1000);
    };

    removeApiError = () => {
        this.form.hideError(this.userInput);
    };

    render() {
        return <Form  onSubmit={this.handleSubmit.bind(this)}>
            <h3>Login</h3>
            <div>
               <label>
                  <Input
                    onFocus={this.removeApiError}
                    ref={c => { this.userInput = c }}
                    placeholder="username"
                    type="text"
                    value="Username"
                    name="username"
                    validations={[required]}
                  />
              </label>
            </div>
            <div>
                <label>
                    Email*
                    <Input value='email@email.com' name='email' validations={[required, email]}/>
                </label>
            </div>
            <div>
                <label>
                    Password*
                    <Input type='password' name='password' validations={[required]}/>
                </label>
            </div>
            <div>
                <Button>Submit</Button>
            </div>
        </Form>;
    }
}

HOC Implementation for integration with Terra components

import { form, control, button } from 'react-validation';

// Define own Form component
const Form = ({ getValues, validate, showError, hideError, children, ...props }) => ( // destruct non-valid props
  <form {...props}>{children}</form>
);

// Define own Input component
const Input = ({ error, isChanged, isUsed, ...props }) => (
  <Field
    error={error}
    help="Example Help"
    required
    isInvalid={error !== null && error !== undefined}
  >
    <Input onChange={props.handleFieldChanged} isInvalid={error !== null && error !== undefined} {...props} />
  </Field>
);

// Define own Button component
const Button = ({ hasErrors, ...props }) => {
  return (
    <button {...props} disabled={hasErrors} />
  );
};

// Now call HOCs on components
const ValidatableForm = form(Form);
const ValidatableInput = control(Input);
const ValidatableButton = button(Button);

<ValidatableForm>
  <ValidatableInput value={this.state.input} onChange={this.changeInput} validations={[required]}/>
</ValidatableForm>
  
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment