Mehmet Yener Yılmaz
Mehmet Yener Yılmaz

Reputation: 251

Formik validate initial values on page load

Code below validate when submit and onFocusOut of textbox fine, What I expect it to trigger validation first reload of the page with initial values.

Tried validateOnMount, as well as others but not worked.

Whats missing here?

const RoleValidationSchema = Yup.object().shape({
    Adi: Yup.string()
        .min(2, "En az 2 karakter olmalıdır")
        .max(30, "En fazla 30 karakter olmalıdır")
        .required("Gerekli!")
})


const Role = (props) => {
    return (
        <div>
            <Formik
                onSubmit={(values, { validate }) => {
                    debugger
                    validate(values);
                    alert("Submietted!")
                    props.handleFormSubmit()
                }}
                initialValues={{
                    Adi: "d"
                }}
                validationSchema={RoleValidationSchema}
                validateOnMount={true}
                validateOnChange={true}
                validateOnBlur={true}
                render={({ errors, touched, setFieldValue, ...rest }) => {
                    debugger
                    return (
                        <Form>
                            <Row>
                                <Col sm="12">
                                    <Label for="Adi">Rol Adi</Label>
                                    <FormGroup className="position-relative">
                                        <Field
                                            autoComplete="off"
                                            id="Adi"
                                            className="form-control"
                                            name="Adi"
                                            type="text"
                                        />
                                        <ErrorMessage name="Adi">
                                            {(msg) => (
                                                <div className="field-error text-danger">{msg}</div>
                                            )}
                                        </ErrorMessage>
                                    </FormGroup>

                                </Col>
                                <Tree dataSource={treeData} targetKeys={targetKeys} expandKeys={[]} onChange={onChange} />
                            </Row>
                            <button type="submit" className="btn btn-success" > Kaydet</button>
                        </Form>
                    )
                }}
            />

        </div>
    )
}

Upvotes: 9

Views: 20530

Answers (7)

Aleksandar
Aleksandar

Reputation: 1339

The only thing that worked for me, was to call focus and blur on the first input text in the form. The ref to the Formik form for some reason was undefined on mount.

Since I use material-ui TextField, I call focus() and blur() on the first input field (material-ui TextField ref.current is the outer div).

useEffect(() => {
  if (textBoxRef.current) {
    setTimeout(() => {
        textBoxRef.current.getElementsByTagName('input')[0].focus();
        setTimeout(() => {
            textBoxRef.current.getElementsByTagName('input')[0].blur();
        }, 50);
    }, 50);
  }
}, [])

Upvotes: -1

irzum shahid
irzum shahid

Reputation: 200

This worked for me to show validation error on form load.

useEffect(() => {
    if (formRef.current) {
      formRef.current.validateForm()
    }
  }, [])

Upvotes: 4

gene b.
gene b.

Reputation: 11984

The only solution I found is to explicitly add initialErrors={{..}} to Formik.

In the below example, it's added depending on some condition. Unfortunately that duplicates the Yup validation/message which I also have in the schema. Nothing else worked, no validateOnMount or anything else.

    <Formik 
        enableReinitialize
        validationSchema={schema} 
        onSubmit={ (values) => {
            submitForm(values);
        }}
        initialValues={initialFormValues}
        /* Unfortunately a duplication of Yup Schema validation on this field,
           but can't force Formik/Yup to validate initially */
        initialErrors={!isEmptyObject(initialFormValues) && 
                       initialFormValues.inactiveApproverCondition && 
                       {'approverId': 'Selected Approver is no longer eligible. Please choose a different Approver to continue.'}}
    >

Upvotes: 1

Nebour
Nebour

Reputation: 105

It's possible to provide a initial value for validation in the "initialIsValid" prop.

const validationSchema= Yup.object()
const initialValues = { ... }
const initialIsValid = schema.isValidSync(initialValues)

return <Formik 
          initialValues={initialValues}
          validationSchema={validationSchema}
          initialIsValid={initialIsValid }
          ...
       >
          ...
       </Formik>

Upvotes: 4

wolendranh
wolendranh

Reputation: 4292

I had a bit specific case with dynamic Yup schema. Schema was generated based on API data. And validateOnMount was failing as when component was mounted there was no schema yet (API response not received yet). I end up with something like this.

Inside component I used useEffect. Notice: I used useRef to be able to reference Formik outside of form.

useEffect(() => {
  if (formRef.current) {
    // check that schema was generated based on API response
    if(Object.keys(dynamicValidationSchema).length != 0){
        formRef.current.validateForm()
    }
  }
}, [initialData, dynamicValidationSchema])

Formik:

    <Formik
        innerRef={formRef}
        enableReinitialize
        initialValues={initialValues}
        validationSchema={validationSchema}
        onSubmit={props.handleSubmit}
    >

Upvotes: 1

Huy Ho
Huy Ho

Reputation: 301

You should try updating your code follow this

render={({ errors, touched, setFieldValue, isValid, ...rest })

and

<button type="submit" className="btn btn-success" disabled={!isValid}> Kaydet</button>

Upvotes: -1

Menawer
Menawer

Reputation: 883

Try to add enableReinitialize Prop to your Formik Component

<Formik
   enableReinitialize
   ......
/>

Upvotes: 2

Related Questions