0
votes

I have a form written using React and Formik. The form currently has 3 fields (for arguments sake, let's assume 3 strings which are validated as required fields using Yup).

If one of the fields holds a particular value I would like to remove a different field, along with the associated validation. ie if field x holds the value 'somestring', I would like field y to appear and be required, but if field x holds a value other than 'somestring', I would like field y to not appear, and consequently not be required.

I am reasonably new to React and Formik validation and so am not sure how to evaluate the current value of a field and alter the rendering based on this.

I am trying to accomplish this using Reacts function components rather than class components.

// react imports
import React, {useContext} from "react";
// style imports
import './NewUser.css'

// hook & context imports
import {useHttpClient} from "../../../Shared/hooks/http-hook";
import AuthContext from "../../../Shared/context/auth-context";

// form validation imports
import * as Yup from 'yup';
import {Field, Form, Formik} from 'formik';


const NewUser = () => {
    const auth = useContext(AuthContext)
    const {sendRequest} = useHttpClient()

    const SignupSchema = Yup.object().shape({
        name: Yup.string().required(),
        conditionalTrigger: Yup.string().required(), // if this field holds 'somestring' then conditionalAffected should render
        conditionalAffected: Yup.string().required()
    });

    return (
                    <Formik
                        initialValues={{
                            name: '',
                            conditionalTrigger: '',
                            conditionalAffected: ''
                        }}
                        validationSchema={SignupSchema}

                        onSubmit={async values => {
                            const response = await sendRequest(
                                `${process.env.REACT_APP_BACKEND_URL}/users/create`,
                                'POST',
                                JSON.stringify(values),
                                {
                                    'Content-Type': 'application/json',
                                    Authorization: 'Bearer ' + auth.token
                                }
                            )
                        }}
                    >
                        {({errors, touched}) => (

                            <Form>
                                <Field name="name" placeholder={"Name"}/>
                                {errors.name && touched.name ? (
                                    <div>{errors.name}</div>
                                ) : null}
                            <Field name="conditionalTrigger" placeholder={"conditionalTrigger"}/>
                                {errors.conditionalTrigger && touched.conditionalTrigger ? (
                                    <div>{errors.conditionalTrigger}</div>
                                ) : null}
                            <Field name="conditionalAffected" placeholder={"conditionalAffected"}/>
                                {errors.conditionalAffected && touched.conditionalAffected ? (
                                    <div>{errors.conditionalAffected}</div>
                                ) : null}


                                <button className={'btn red'} type="submit">Submit</button>
                            </Form>
                        )}
                    </Formik>
    )
}

export default NewUser
1

1 Answers

1
votes

you should change your validation to become something like this:

conditionalTrigger: Yup.string().required(),
conditionalAffected:  Yup.string().when('conditionalTrigger', {
   is: (val) => val == "something",
   then: Yup.string().required('This field is required')
}),