Nested Formik Validation Not Functioning Properly on Child Inputs

25 Views Asked by At

When I use Formik and Yup for validating the form, it only validates the main input fields when I click on the submit button. It works when I focus on the fields and then click somewhere else, triggering the validation on blur. However, when I click on submit, it does not validate the child fields.

 const validationSchema = Yup.object().shape({
        complaintType: Yup.string().required('Please select a payment type'),
        fullName: Yup.string().required('Please Enter FullName'),
        accountNo: Yup.string()
            .required('Please Enter Account No')
            .matches(/^\d+$/, 'Account number must contain only numbers')
            .matches(
                /^(?:\d{11}|\d{12}|\d{14})$/,
                'Account number must be 11, 12, or 14 digits'
            ),
        atm: Yup.object().when('complaintType', {
            is: 'ATM',
            then: () => Yup.object().shape({
                atmId: Yup.string().required("Atm id is required"),
                cardNumber: Yup.string().required('Card number is required'),
                amount: Yup.number().required('Amount is required').positive('Amount must be positive'),
            }),
            otherwise: () => Yup.object(),
        }),
    });

this is my validation schema

const initialValues = {
        complaintType: '',
        fullName: '',
        atm: {
            cardNumber: '',
        },
        pos: {
            debitedAmount: '',
            billAmount: '',
        },
    };


 <Formik
                initialValues={initialValues}
                validationSchema={validationSchema}
                onSubmit={(values) => {
                    console.log('Submitted values:', values);
                }}
            >
                {({ values, errors, touched, handleChange }) => (
                    <Form>
<div className='row'>
                            <div className="col-md-6 col-sm-6 mb-3">
                                <label htmlFor="complaintType" className="form-label">Complaint Type:</label>
                                <Field as="select" name="complaintType" onChange={handleChange} className={`form-control text-center ${errors.complaintType && touched.complaintType ? 'error' : ''}`} style={{ borderColor: errors.accountNo && touched.accountNo ? 'red' : '' }}>
                                    <option value="" disabled>-- Select Complaint --</option>
                                    <option value="ATM">ATM COMPLAINT</option>
                                    <option value="POS">POS (SHOPPING) COMPLAINT</option>
                                    <option value="IMPS">IMPS COMPLAINT</option>
                                    <option value="UPI">UPI COMPLAINT</option>
                                </Field>
                                {errors.complaintType && touched.complaintType && (
                                            <div className="error-message" style={{ color: 'red' }}>{errors.complaintType}</div>
                                )}
                            </div>
                        </div>
<div className="col-md-4 col-sm-6 mb-3">
                                    <div className='form-group'>
                                        <label htmlFor='fullName' className='input-label'>Full Name</label>
                                        <Field
                                            id="fullName"
                                            type="text"
                                            name="fullName"
                                            placeholder="Enter Full Name"
                                            className={`form-control mt-1 ${errors.fullName && touched.fullName ? 'error' : ''}`}
                                            style={{ borderColor: errors.fullName && touched.fullName ? 'red' : '' }}
                                        />
                                        {errors.fullName && touched.fullName && (
                                            <div className="error-message" style={{ color: 'red' }}>{errors.fullName}</div>
                                        )}
                                    </div>
                                </div>

{values.complaintType === 'ATM' && (
                                <>
                                    <div className='row justify-content-center mb-4 h5'> ATM Complaint </div>
                                    <div className='row'>

                                        <div className="col-md-4 col-sm-6 mb-3">
                                            <div className='form-group'>
                                                <label htmlFor='atmCard' className='input-label'>cardNumber</label>
                                                <Field
                                                    id="atmCard"
                                                    type="text"
                                                    name="atm.cardNumber"
                                                    placeholder="Enter Card Number"
                                                    className={`form-control mt-1 ${errors.atm && errors.atm.cardNumber && touched.atm && touched.atm.cardNumber ? 'error' : ''}`}
                                                    style={{ borderColor: errors.atm && errors.atm.cardNumber && touched.atm && touched.atm.cardNumber ? 'red' : '' }}
                                                />
                                                {errors.atm && errors.atm.cardNumber && touched.atm && touched.atm.cardNumber && (
                                                    <div className="error-message" style={{ color: 'red' }}>{errors.atm.cardNumber}</div>
                                                )}
                                            </div>
                                        </div>


                                    </div>
                                </>
                            )}
<button type="submit" className="btn btn-primary">Submit Complaint</button>
                    </Form>
                )}
            </Formik>

I want the nested validation to occur dynamically when I select a dropdown option or change an input field. In other words, I need real-time validation to happen as I interact with the form.

0

There are 0 best solutions below