1.0.0 • Published 5 years ago

gc-react-form-validation v1.0.0

Weekly downloads
3
License
ISC
Repository
github
Last release
5 years ago

GC React form-validation

React form validation and UI library

This library has two components

  1. Input
  2. Form

Input can be used separately from the Form component, while the Form component makes use of the Input component.

Form checks to see whether all the Inputs have been passed validation and submits the form accordingly. At the moment custom inputs are not supported, as form data needs to be in the object to be validated.

Installation

npm install gc-react-form-validation

Usage

Styles

gc-react-form-validation exposes the stylesheets as both the original scss form (lib/scss) and the processed css form (lib/main.css). Import either in whichever way makes sense for your own project (e.g. via a webpack loader, or via a scss entry point).

Below are variables available to override colour pallette:

$gc-form-light-grey: #e2e2e2;
$gc-form-grey: #f3f3f3;
$gc-form-med-grey: #cfcfcf;
$gc-form-dark-grey: #909090;
$gc-form-black: #44474b;

$gc-form-red: #c46e6b;
$gc-form-input-bg: #ffffff;
$gc-form-primary-colour: #e8bddb;

To change the font edit this variable:

$gc-form-font: 'Andale Mono', Tahoma !default;

Scripts

To use Form Component.

import { Form } from 'gc-react-form-validation';

...

constructor(props) {
  super(props);
  this.state = {
    serverErrors: [],
    name: '',
    lastName: '',
    email: '',
    birthdate: '',
    favoriteAnimal: '',
    multi: ['pheonix', 'goldfish'],
  }
}

handleChange(value, name) {
  // Receives input value and state name
  this.setState({[name]: value});
}

formSubmitted() {
  // Stuff to do once form is successfully validated
}

render() {
  const today = new Date();
  const thisYear = today.getFullYear();
  const minAgeDate = new Date(thisYear - 5, 1, 1);

  // Form data object.
  const formFields = {
    firstName: {
      name: 'name', // Required
      stateName: 'name', // Optional if missing name of object will be used e.g. firstName
      type: 'text', // Required or validation
      label: 'Name',
      value: this.state.name, // Required
      required: true
    },
    lastName: { // Minimum fields
      type: 'text',
      label: 'Surname',
      value: this.state.lastName
    },
    email: {
      type: 'email',
      label: 'Email Address',
      value: this.state.email,
      customRegex: '/asdf@*/',
      required: true
    },
    birthdate: {
      type: 'date',
      label: 'Date of Birth',
      value: this.state.birthdate,
      customErrorMessage: 'User must be at least 5 years old',
      maxDate: minAgeDate,
    },
    favoriteAnimal: {
      type: 'select',
      label: 'Favourite Animal',
      search: true,
      required: true,
      hidden: false,
      value: this.state.favoriteAnimal,
      options: [{
          label: 'Unicorn',
          value: 'unicorn'
        }, {
          label: 'Pheonix',
          value: 'pheonix'
        }, {
          label: 'Dragon',
          value: 'dragon'
        }, {
          label: 'Goldfish',
          value: 'goldfish'
      }]
    },
    multi: {
      type: 'select',
      label: 'Muliple Select Label',
      value: this.state.multi,
      multi: true,
      search: true,
      options: [{
          label: 'Unicorn',
          value: 'unicorn'
        }, {
          label: 'Pheonix',
          value: 'pheonix'
        }, {
          label: 'Dragon',
          value: 'dragon'
        }, {
          label: 'Goldfish',
          value: 'goldfish'
      }]
    }
  };

  // Can add divs to place form objects
  return (
    <div>
      <Form
        data={formFields}
        extendedClassNames="custom-classes"
        submissionErrorMessages={this.state.serverErrors} // For displaying errors after submission
        onSubmit={() => this.formSubmitted()}
        onInputChange={(v, t) => this.handleChange(v, t)}>
          {({ fields }) => (
            <div>
              {fields.firstName}
              {fields.lastName}
              {fields.email}
              <div className="float-left">
                {fields.birthdate}
              </div>
              {fields.favoriteAnimal}
              {fields.multi}
              <button>Submit Form</button>
            </div>
          )}
      </Form>
    </div>
  );
}

If you want to use the Input component separately

import { Input } from 'gc-react-form-validation';

...

<Input
  onChange={val => this.handleChange(val, 'text')}
  value={this.state.text}
  name="nameTxt"
  placeholder="Type something that starts with a 'W'."
  customRegex={/\bW/g}
  customErrorMessage="Must start with uppercase W"
  type="text"
/>

Using Custom Input Components

There are two ways of adding custom input components to the Form, ie. adding it to the Form template or adding it via the customComponent input field object property if you are using a wrapper of some sort

Via Template

To add custom UI Components to Form via the template, put the custom component inside the template with a reference to the field below it. The reference represents where the error validation message would appear.

In the field object add the prop customUI: true to prevent the library UI from rendering.

The input would be validated everytime the input value changes.

customDatePicker: {
  ...
  customUI: true,
  type: 'date'
  ...
}
...

{({ fields }) => (
  <div>
    <CustomDatePicker/>
    {fields.customDatePicker}
    {fields.email}
    <button>Submit Form</button>
  </div>
)}

...

Via customComponent

To add a custom input component via the customComponent callback. The custom input component will be passed all the input properties including handleInputChange and handleInputValidation callbacks.

This method is best when dealing with more complicated form structures like when wrapping the form in its own wrapper to handle state and fields are created dynamically.

customDatePicker: {
  ...
  customComponent: ({
    value,
    handleInputChange,
    handleInputValidation
  }) => (
    <CustomDatePicker
    date={value}
    onChange={ newValue => handleInputChange(newValue)}
    onBlur={() => handleInputValidation(value)} />
  ),
  type: 'date'
  ...
}
...

{({ fields }) => (
  <div>
    {fields.customDatePicker}
    {fields.email}
    <button>Submit Form</button>
  </div>
)}

...

Input Props

Some more props you can use.

PropertyDefinitionRequiredOptions
typeDetermines the type of validation and type of input to renderRequiredtext, email, password, date, range, name, textarea, select
stateNameAccepts state variables to change the input name of input field objectOptional
customUIAccepts boolean valueOptionaltrue, false (default)
onChangePass function to handle state changes when input value is changedRequired
extendedClassNamesCSS class for adding custom styling.Optional
valueAccepts values for inputRequired
disabledWhen disabled is false the input field is disabledOptionaltrue, false (default)
maxLengthMaximum character lengthOptional
minLengthMinimum character lengthOptional
maxDateLatest date, accepts date objectOptional
minDateEarliest date, accepts date objectOptional
maxHighest accepted numberOptional
minLowest accepted numberOptional
autocompleteInformation for browser autocompleteOptional
multiWhen used with 'select' type allows for a multiple select listOptional

Translations

To add translations to the validation messages pass a translation object to the translations prop of either the Form or Input component. If no translation object is found then default translations will be used.

Each key/value pair corresponds to text in the library and must return a function.

Here is an example of the expected translation object:

const translationsExample = {
  invalidEmailAddress: () => 'This email address is invalid',
  maxCharLength: max => `May not contain more than ${max} characters`,
  minCharLength: min => `May not contain less than ${min} characters`,
  invalidURL: () => 'This URL is invalid',
  minPasswordCharLength: min => `Password may not contain less than ${min} characters`,
  dateRange: (fromDate, toDate) => `Choose a date between ${fromDate.toDateString()} and ${toDate.toDateString()}`,
  maxDateRange: toDate => `Choose a date earlier than ${toDate}`,
  minDateRange: fromDate => `Choose a date later than ${fromDate}`,
  maxNumber: max => `Choose a number lower than ${max}`,
  minNumber: min => `Choose a number higher than ${min}`,
  maxSelectOptions: max => `May not select more than ${max} options`,
  minSelectOptions: min => `May not select less than ${min} options`,
  requiredField: () => 'This is a required field',
  defaultInvalidInput: () => 'Invalid input'
}

...

<Form
  ...
  translations={translationsExample}
  ...
>
...

Updates

Gc-react-form-validation recently underwent an update with a few breaking changes.

The ui has also changed. Floating labels was removed in favour of bordered input containers.

Property name changes

  • handleInputChange on the Form component becomes onInputChange.
  • isVisible on the Input component is no longer used instead use hidden.
  • title on the Input component is no longer used instead use label.

New features

  • stateName is no longer required, instead input field object name will be used when no stateName is provided.
  • onInputValidationSuccess and onFormValidationSuccess are callbacks that can be passed to the Input and Form components, respectively, that get triggered when they are successfully validated. Useful for disabling submission buttons.
  • onInputValidationFailure and onFormValidationFailure are callbacks that can be passed to Input and Form components respectively that are triggered when the Input or Form component fails validation. onInputValidationFailure returns an error message relative to the input. onFormValidationFailure returns an error object with all the errors in the Form component.

Last stable release before update: 0.7.83

JavaScript Style Guide

1.0.0

5 years ago

0.7.83

5 years ago

0.7.82

5 years ago

0.7.81

5 years ago

0.7.8

5 years ago

0.7.7

6 years ago

0.7.6

6 years ago

0.7.5

6 years ago

0.7.4

6 years ago

0.7.3

6 years ago

0.7.2

6 years ago

0.7.1

6 years ago

0.7.0

6 years ago

0.6.9

6 years ago

0.6.8

6 years ago

0.6.7

6 years ago

0.6.6

6 years ago

0.6.5

6 years ago

0.6.4

6 years ago

0.6.3

6 years ago

0.6.1

6 years ago

0.6.0

6 years ago

0.5.12

6 years ago

0.5.11

6 years ago

0.5.10

6 years ago

0.5.9

6 years ago

0.5.8

6 years ago

0.5.7

6 years ago

0.5.6

6 years ago

0.5.5

6 years ago

0.5.4

6 years ago

0.5.3

6 years ago

0.5.2

6 years ago

0.5.1

6 years ago

0.5.0

6 years ago

0.4.6

6 years ago

0.4.5

6 years ago

0.4.4

6 years ago

0.4.3

6 years ago

0.4.2

6 years ago

0.3.13

6 years ago

0.3.12

6 years ago

0.3.11

6 years ago

0.3.10

6 years ago

0.3.9

6 years ago

0.3.8

6 years ago

0.3.7

6 years ago

0.3.6

6 years ago

0.3.5

6 years ago

0.3.4

6 years ago

0.3.3

6 years ago

0.3.2

6 years ago

0.3.1

6 years ago

0.2.9

6 years ago

0.2.8

7 years ago

0.2.7

7 years ago

0.2.6

7 years ago

0.2.5

7 years ago

0.2.4

7 years ago

0.2.3

7 years ago

0.2.2

7 years ago

0.2.1

7 years ago

0.2.0

7 years ago

0.1.3

7 years ago

0.1.2

7 years ago

0.1.1

7 years ago