3

TL;DR: React provide controlled component, HOC, that is the base idea for React validation library in NPM. However, the weak point is integration with existence Component such as React Select and custom display place of error message

I am migrating from traditional coding jQuery and PHP (used for real and big project for years, not student learn to play code). I focus most of my time on FORM because client's request always about FORM.

Now with FORM, the most important part is validation method/plugin. First forget about some guys tell us about "With React you could easily do controlled component so we do not need validation plugin". Our FORM in production required hundred of Field with many Tabs (for example a personnel form or some crazy organization report), so coding per field is not practical, it s like traditional js coding to validate form.

Come to library, I test and found these three maybe good enough.

  1. React-Validation
  2. React Validation Mixin
  3. Formsy

I will not go into detail about these lib, but the way they work is similar. We must create a component for input, select, textarea and form to make them work. Inside Input component, we define how Input border change class to make border error red and How error message apprear (in div or span below Input).

(There are other validation libs but their method is a json validation for form or even create form with json, that s not my choice because I want to validate form just by a simple attribute in input such as [required, email], not wasting time on ton of definition json)

Now I stuck with this technique in these case:

1. Integration with existence excellent component

I download excelent component from NPM to solve some specific function (like React Select). Now to to the real job, we must validate input for these custom component. This come to an extra work, we must integrate validation to any extra component found. I bang my head to wall to figure out using HOC to validate React Select like this (React-Validation code). And to make this work, I must modify origin HOC to create a custom HOC.

  // Define own Input component 
  function MySelect({ error, isChanged, isUsed, ...selectProps }) {
      return(
         
        <div>
            <Select onChange={selectProps.onChange.bind(this)} {...selectProps} {...( isChanged && isUsed && error ? {
            className: `is-invalid-input ${selectProps.className}`
          } : { className: selectProps.className } )} />
            <input type="hidden"  {...selectProps}  />
          {isChanged && isUsed && error}
        </div>
      ) 
  } 

  const MyValidationSelect = controlSelect(MySelect); //My custom HOC

Now, I cannot think more to work with this technique in future. Imagine we have project and need an extra component. We do not have much time to code our self so download a library. BOOM*, we bang our head to wall to figure out how to make custom component validate. We will waste time on "side project", not the main task (client request feature).

2. Custom place for validation message

Component is good, but it also wrap code inside a layout. Error message must be a part in Input Component. Now come the hard part, some crazy client require to put error message on top of form, or in a modal box. In this case, I still cannot think out a solution if using wrapping Input and error in component.

3. My dirty solution

jQuery appear for long enough for jQuery lib become mature. Validation with jquery could be solve with so called jQuery Validation . Any case we think out for valition could be solved easily and elegant with this lib (custom error placement, custom field, custom validator, custom error format (not just css thing)...)

I just to make jQuery validation with with React form in ComponentDidMount and it work as it is. It is also simple to integrate validation for any custom react component by writing to a "validation config file" with errorPlacement, highlight, success function API.


Thanks for anyone reach this line, this is really a long topic. And here is my question: I tried to "think in react" but cannot solve the simplest thing: React form validation.

Thanks for any hint for me to solve this issue.

Zacharias
  • 78
  • 1
  • 1
  • 6

4 Answers4

2

I have built a custom Hook for easy form validation, maybe you will find it useful.

Github: https://github.com/bluebill1049/react-hook-form website: https://react-hook-form.now.sh

quick code example below

import React from 'react'
import useForm from 'react-hook-form'

function App() {
  const { register, handleSubmit, errors } = useForm() // initialise the hook
  const onSubmit = (data) => { console.log(data) } // callback when validation pass

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input name="firstname" ref={register} /> {/* register an input */}

      <input name="lastname" ref={register({ required: true })} /> {/* apply required validation */}
      {errors.lastname && 'Last name is required.'} {/* error message */}

      <input name="age" ref={register({ pattern: /\d+/ })} /> {/* apply a Refex validation */}
      {errors.age && 'Please enter number for age.'} {/* error message */}

      <input type="submit" />
    </form>
  )
}
Bill
  • 17,872
  • 19
  • 83
  • 131
0

I faced the same issue therefore I wrote little package myself:

https://www.npmjs.com/package/validate-react

this takes care of simple validations without any need of redux or renamed tags.

Aman
  • 1,292
  • 1
  • 14
  • 20
  • Sorry to but I found your solution nothing different React Validation with preset Field container . So problem still not solved – Zacharias Nov 17 '17 at 08:45
0

use react-forms-validator the fluent form validation for react

react-forms-validator

Component to provide simple form validation for React components.

If you find any bug or error, please feel free to raise an issue. Pull requests are also welcome.

Installation

npm i -S react-forms-validator

Example usage

first of all import the module.

That's it. We can now use it in our React components:

import Validator from 'react-forms-validator';

import React, { Component } from 'react';
import Validator from 'react-forms-validator';

class Login extends React.Component{

    constructor( props ){
        super( props );
        this.state = {
            contact_no:"",
            password:"",
            submitted:false,
        };
        this.handleChange = this.handleChange.bind(this);
        this.handleFormSubmit = this.handleFormSubmit.bind(this);
        this.isValidationError = this.isValidationError.bind(this);
        this.flag= true;
        this.isFormValidationErrors = false;
    }


    handleChange(event){
        let { name, value } = event.target;
        this.setState( { [name]:value } );
        let { submitted } = this.state;
    }
    isValidationError(flag){
        this.isFormValidationErrors = flag;
    }

    handleFormSubmit(event){
        event.preventDefault();
        this.setState( { submitted:true } );
        let { contact_no, password } = this.state;
        if ( !this.isFormValidationErrors ){
            //you are ready to dispatch submit action here.
        }
    }

    render() {
        let { contact_no, password, submitted } = this.state;
        return(
            <div>
                <form noValidate onSubmit={this.handleFormSubmit}>
                    <div className="formgroup">
                        <Input 
                            type="text" name="email" 
                            placeholder="Contact number" 
                            value={ contact_no } 
                            onChange={ this.handleChange }/>
                            <Validator 
                                isValidationError={this.isValidationError}
                                isFormSubmitted={submitted} 
                                reference={contact_no}
                                validationRules={{required:true,number:true,maxLength:10}} 
                                validationMessages={{required:"This field is required",number:"Not a valid number",maxLength:"Not a valid number"}}/>
                    </div>
                    <div className="formgroup">
                        <Input 
                            type="password" 
                            name="password" 
                            placeholder="Password" 
                            value={ password } 
                            onChange={ this.handleChange } 
                            autoComplete/>
                            <Validator 
                                isFormSubmitted={submitted} 
                                reference={password} 
                                validationRules={{required:true}} 
                                validationMessages={{required:"This field is required",}}/>

                    </div>
                    <div>
                        <button type="submit">Sign In</button>
                    </div>
                </form>
            </div>  
        )
    }
}

Component and props

react-forms-validator provides a Validator component. Also provide five (5) required props. For now all props are required.

isValidationError function.

isFormSubmitted boolean [true|false].

reference reference to input value. State value like contact_no and password in above example.

validationRules object. chack below for available rules.

validationMessages object.

Note:: key of validationRules object and validationMessages should be same and required.

Prakash Naidu
  • 742
  • 2
  • 7
  • 17
0

In functional component case . Library for Functional component In class component case . Library for Class component.

Click on the href of both and get it. Do up vote, if it helps!

sid7747
  • 690
  • 7
  • 15