6
votes

In my app I use React Bootstrap and Formik. I want the bootstrap to show that field is invalid (for example is not an email but should be) after I press the submit button. And then when I start typing new values to fields it should disappear. In the tutorial I used I only found the way to show that field is invalid only at the same moment the user is typing the values?

How to do that? How to set isInvalid to show errors only after submit using Formik?

Here is my current code

import * as yup from "yup";
import React from "react";
import Form from "react-bootstrap/Form";
import Button from "react-bootstrap/Button";
import {Formik} from "formik";
import {loginActions} from "../_actions/loginActions";
import {connect} from "react-redux";
import {loginService} from "../_services";

const schema = yup.object().shape({
    username: yup.string().email("Login musi być w formie e-mail").required("Wypełnij pole login"),
    password: yup.string().required("Wypełnij pole hasło")
});

class LoginForm extends React.Component {

    constructor(props) {
        super(props);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleSubmit(e) {
        const {username, password} = e;
        if (username && password) {
            loginService
                .login(username, password)
                .then(
                    success => {
                        const data = success.data;
                        if (success.status === 200 && data.success === true) {
                            return {...data.user, password: password};
                        } else if (success.status === 400) {
                            window.location.reload();
                        }
                        const error = (!data.success && "Wrong credentials") || success.statusText;
                        return Promise.reject(error);
                    }
                )
                .then(auth => {
                    this.props.login(auth)
                })
        }
    }

    render() {
        return (
            <Formik
                validationSchema={schema}
                onSubmit={e => this.handleSubmit(e)}
                initialValues={{username: '', password: ''}}>
                {
                    formProps => (
                        <Form name='form' onSubmit={formProps.handleSubmit}>
                            <Form.Group noValidate controlId="loginForm.username">
                                <Form.Label>Adres e-mail</Form.Label>
                                <Form.Control
                                    type="text"
                                    name="username"
                                    value={formProps.values.username}
                                    onChange={formProps.handleChange}
                                    isInvalid={!!formProps.errors.username}
                                />
                                <Form.Control.Feedback type="invalid">
                                    {formProps.errors.username}
                                </Form.Control.Feedback>
                            </Form.Group>
                            <Form.Group controlId="loginForm.password">
                                <Form.Label>Hasło</Form.Label>
                                <Form.Control
                                    type="password"
                                    name="password"
                                    value={formProps.values.password}
                                    onChange={formProps.handleChange}
                                >
                                </Form.Control>
                                <Form.Control.Feedback type="invalid">
                                    {formProps.errors.password}
                                </Form.Control.Feedback>
                            </Form.Group>
                            <Form.Group controlId="loginForm.loginBtn">
                                <Button variant="primary" type="submit">
                                    Zaloguj się
                                </Button>
                                {formProps.isSubmitting &&
                                (
                                    <img
                                        src="data:image/gif;base64,R0lGODlhEAAQAPIAAP///wAAAMLCwkJCQgAAAGJiYoKCgpKSkiH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQJCgAAACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkECQoAAAAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkECQoAAAAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkECQoAAAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQJCgAAACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQJCgAAACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAkKAAAALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOwAAAAAAAAAAAA=="
                                    />)
                                }
                            </Form.Group>
                        </Form>
                    )
                }
            </Formik>
        )
    }
}


function mapState(state) {
    const {session} = state;
    return {session}
}

const connectedLoginForm = connect(mapState, {login: loginActions.login})(LoginForm);
export {connectedLoginForm as LoginForm};
1
You should check formik documentation on When does validation run (jaredpalmer.com/formik/docs/guides/…) and also the dirty (jaredpalmer.com/formik/docs/api/formik#dirty-boolean) prop. - damjtoh

1 Answers

15
votes

Formik validation runs, onChange, onBlur and onSubmit respectively. So in your case if you want it to be validated only on submit, you should pass validateOnChange,validateOnBlur props as false.

<Formik
   initialValues={{ email: '', password: '' }}
   validationSchema={LoginSchema}
   validateOnChange={false}
   validateOnBlur={false}
   onSubmit={values => onLogin(values)}>
     ...
 />