Code Monkey home page Code Monkey logo

react-class-validator's Introduction

react-class-validator

Easy-to-use React hook for validating forms with the class-validator library.

Build Status codecov

Installation

npm install --save react-class-validator
const validatorOptions: ValidatorContextOptions = {
    onErrorMessage: (error): string => {
        // custom error message handling (localization, etc)
    },
    resultType: 'boolean' // default, can also be set to 'map'
}

render((
    <ValidatorProvider options={validatorOptions}>
        <MyComponent />
    </ValidatorProvider>
), document.getElementById('root'))

Default onErrorMessage behavior

The default behavior is to flatten all error constraints for each attribute.

const getDefaultContextOptions = (): ValidatorContextOptions => ({
    onErrorMessage: (error) => Object.keys(error.constraints).map((key) => error.constraints[key])
});

react-intl

When using libraries such as react-intl, you don't have to modify the existing onErrorMessage handler. Decorators are handled at source load, so you only need to include the intl.formatMessage in your message definition.

class Person {

    @IsEmail({}, {
        message: intl.formatMessage(defineMessage({defaultMessage: 'Invalid email'}))
    })
    @IsNotEmpty({
        message: intl.formatMessage(defineMessage({defaultMessage: 'Email cannot be empty'}))
    })
    public email: string;
    
}

Usage

Create a class using validation decorators from class-validator.

import { IsNotEmpty } from "class-validator";

class LoginValidation {

    @IsNotEmpty({
        message: 'username cannot be empty'
    })
    public username: string;

    @IsNotEmpty({
        message: 'password cannot be empty'
    })
    public password: string;

}

Set up your form component to validate using your validation class.

const MyComponent = () => {

    const [username, setUsername] = useState('');
    const [password, setPassword] = useState('');

    const [validate, errors] = useValidation(LoginValidation);

    return (
        <form onSubmit={async (evt) => {

            evt.preventDefault();

            // `validate` will return true if the submission is valid
            if (await validate({username, password})) {
                // ... handle valid submission
            }

        }}>

            {/* use a filter so that the onBlur function will only validate username */}
            <input value={username} onChange={({target: {value}}) => setUsername(value)}
                onBlur={() => validate({username}, ['username'])}/>

            {/* show error */}
            {errors.username && (
                <div className="error">
                    {errors.username.map((message) => <strong>message</strong>)}
                </div>
            )}

        </form>
    );

};

Usage With Formik

react-class-validator easily integrates with Formik. You can simply use the validate function returned from useValidation, so long as the Formik fields are named the same as the keys in your validation class. Individual fields will have to be validated with onBlur functionality.

Formik error messages

To display error messages without custom handling, messages will need to be outputted as a map upon validation. Do this by overriding the default resultType (you can also do this at the component-level).

const options: ValidatorContextOptions = {
    resultType: 'map'
};

Then you can simply integrate with the default Formik flow.

export const Login: FunctionComponent = () => {

    const [validate] = useValidation(LoginValidation);

    return (
        <Formik initialValues={{username: '', password: ''}}
                validateOnBlur
                validateOnChange
                validate={validate}>
            {({values, touched, errors, handleChange, handleBlur}) => (
                <Form>
                    
                    <label htmlFor="username">Username</label>
                    <Field id="username" name="username" placeholder="Username" />

                    {errors.username && touched.username ? (
                        <div>{errors.username}</div>
                    ) : null}
                    
                    {/* other fields */}
                    
                    <button type="submit">
                        Submit
                    </button>
                    
                </Form>
            )}
        </Formik>
    );
};

Contributors

Library built and maintained by Robin Schultz

If you would like to contribute (aka buy me a beer), you can send funds via PayPal at the link below.

paypal

react-class-validator's People

Contributors

anigenero avatar dependabot[bot] avatar jpedroh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

react-class-validator's Issues

(CRA) Example from readme throws: Module parse failed: Unexpected character '@'

When I follow steps from readme example usage, app (create-react-app - "react-scripts": "4.0.3") throws:

Module parse failed: Unexpected character '@'
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders

Is there any additional configuration required?

TypeError: Cannot read property 'onErrorMessage' of null

image

With this in my _app.tsx file... I'm using Next.js

import { ValidatorProvider as FormValidatorProvider } from 'react-class-validator';

...

<FormValidatorProvider>
    <Component {...pageProps} />
</FormValidatorProvider>

These work

<FormValidatorProvider options={undefined}> ...
//OR
<FormValidatorProvider options={{}}>...

Nested Validation

Nested validation does not work even after using the class transformer package.

Add i18n support

Hey,

First of all, awesome library! Just what we needed.

We will be using class-validator both on the front and back-end with a shared model, however when displaying errors on the front-end we'd like to have them translated via keys (using react-i18next).

I think class-validator doesn't support i18n out-of-the-box, but a monkey patch currently exists that acts as a workaround.

Perhaps we could hook into this and allow the user to supply their own i18n keys for each ValidationType via this monkey patch, until official support arrives? I think this will benefit a lot of users in the long run -- allowing more people to be able use this library as well ๐Ÿ˜„.

Let me know what you think!

Jeroen

Error message of filter won't disappear when updated

There's an issue in which an error message will not disappear even if a valid value has been placed after. This bug only happens if you are using validation filters.

Steps to reproduce

Here's a minimum:

import 'reflect-metadata';
import React, {FunctionComponent, useState} from "react";
import {useValidation} from "react-class-validator";
import {IsNotEmpty} from "class-validator";

class FormValidation {
    @IsNotEmpty({ message: 'First name cannot be empty' })
    public firstName: string;

    @IsNotEmpty({  message: 'Last name cannot be empty' })
    public lastName: string;
}

const Form: FunctionComponent = () => {
    const [firstName, setFirstName] = useState('');
    const [lastName, setLastName] = useState('');

    const [validate, errorMessages] = useValidation(ContactFormValidation);

    return (
        <form>
            <input value={firstName} onChange={({target: {value}}) => setFirstName(value)}
                   onBlur={() => validate({firstName}, ['firstName'])}/>
            {errorMessages.firstName && errorMessages.firstName.map((error, index) => (
                <strong key={index}>{error}</strong>
            ))}
            <input value={lastName} onChange={({target: {value}}) => setLastName(value)}
                   onBlur={() => validate({lastName}, ['lastName'])}/>
            {errorMessages.lastName && errorMessages.lastName.map((error, index) => (
                <strong key={index}>{error}</strong>
            ))}
        </form>
    );
};

Then, try bluring first name only and you will see not empty error message. If you then type a valid value, the error message will not disappear.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.