Search code examples
reactjsreact-bootstrapformikyup

(React, Formik & Yup) Disable or/and change a class of the submit button


So, I've made a registration form in the React App, using Bootstrap for the style, Formik and Yup for the validation. I want to change a Submit Button class to 'btn-outline-danger' and make it disabled till the form inputs are valid. I know it doesn't affect the real functionality, but anyways I'd like to manipulate with the button's style.

import React from 'react';
import { Button, Form as FormStrap } from 'react-bootstrap';
import { Link } from 'react-router-dom';
import * as yup from 'yup';
import { Formik, Form, Field } from 'formik';

const REGISTRATION_SCHEMA = yup.object().shape({
    name: yup
        .string()
        .min(2, 'Too Short!')
        .max(24, 'Too Long!')
        .required('Required'),
    email: yup.string().email('Invalid email').required('Required'),
    password: yup
        .string()
        .min(6, 'Too Short!')
        .max(14, 'Too Long!')
        .required('Required'),
    passwordConfirmation: yup
        .string()
        .oneOf([yup.ref('password'), null], 'Passwords do not match'),
});

export default function RegistrationForm() {
    return (
        <>
            <Formik
                validationSchema={REGISTRATION_SCHEMA}
                initialValues={{
                    name: '',
                    email: '',
                    password: '',
                    passwordConfirmation: '',
                }}
                onSubmit={(values) => {
                    // same shape as initial values
                    console.log(values);
                }}
                // validate={validate}
            >
                {({ handleSubmit, handleChange, values, touched, errors }) => (
                    <Form id='registration-form' onSubmit={handleSubmit}>
                        <FormStrap.Group className='mb-3' controlId='registration-name'>
                            <FormStrap.Label>Name</FormStrap.Label>
                            <Field
                                className='form-control'
                                type='text'
                                placeholder='Enter name'
                                name='name'
                                value={values.name}
                                onChange={handleChange}
                            />
                            {errors.name && touched.name ? (
                                <FormStrap.Text>{errors.name}</FormStrap.Text>
                            ) : null}
                        </FormStrap.Group>
                        <FormStrap.Group className='mb-3' controlId='registration-email'>
                            <FormStrap.Label>Email </FormStrap.Label>
                            <Field
                                className='form-control'
                                type='email'
                                placeholder='Enter email'
                                name='email'
                                value={values.email}
                                onChange={handleChange}
                            />
                            {errors.email && touched.email ? (
                                <FormStrap.Text>{errors.email}</FormStrap.Text>
                            ) : null}
                        </FormStrap.Group>
                        <FormStrap.Group className='mb-3' controlId='registration-password'>
                            <FormStrap.Label>Password</FormStrap.Label>
                            <Field
                                className='form-control'
                                type='password'
                                placeholder='Enter password'
                                name='password'
                                value={values.password}
                                onChange={handleChange}
                            />
                            {errors.password && touched.password ? (
                                <FormStrap.Text>{errors.password}</FormStrap.Text>
                            ) : null}
                            <Field
                                className='mt-2 form-control'
                                type='password'
                                placeholder='Confirm password'
                                name='passwordConfirmation'
                                value={values.passwordConfirmation}
                                onChange={handleChange}
                            />
                            {errors.passwordConfirmation && touched.passwordConfirmation ? (
                                <FormStrap.Text>{errors.passwordConfirmation}</FormStrap.Text>
                            ) : null}
                        </FormStrap.Group>
                        <FormStrap.Group className='mb-3' controlId='registration-submit'>
                            <Button variant='success' type='submit' disabled={!errors}>
                                Sign Up
                            </Button>
                        </FormStrap.Group>
                        <FormStrap.Group className='mb-3'>
                            <FormStrap.Text className='text-muted'>
                                Already have an account? <Link to='/login'>Sign in now</Link>
                            </FormStrap.Text>
                        </FormStrap.Group>
                    </Form>
                )}
            </Formik>
        </>
    );
}

Solution

  • I will rewrite just the button part

    <FormStrap.Group className='mb-3' controlId='registration-submit'>
        <Button
                variant='success'
                type='submit'
                disabled={Object.keys(errors).length > 0}
                className={`${Object.keys(errors).length > 0 ? 'btn-outline-danger': ''}`}>
            Sign Up
        </Button>
    </FormStrap.Group>