Search code examples
javascriptreactjsformikant-design-proreact-forms

formik with custo style (ant design)


I made a reusable formik form, but I want to use ant select instead of formik select. the Error message is not working with ant design and I dont know how to configure that. I need to show the error message when it's not validated. in console.log there is no problem it wworks perfect as i change the ant select. But the errortext does not shows

import React from "react";
import { Formik } from "formik";
import {Form} from 'antd'
import * as Yup from "yup";
import FormikController from "../components/Forms/FormikController";
const city = [
  { key: "option 1", value: "option1" },
  { key: "option 2", value: "option2" },
  { key: "option 3", value: "option3" },
  { key: "option 4", value: "option4" },
 ];
const Contact = () => {
  const initialValues = {
    whoYouAre: "",
    email: "",
    message: "",
  };
  const validationSchema = Yup.object({
    whoYouAre :Yup.string().required(),
    email :Yup.string().required()
  });
  return (
      <Container className="contact">
            <h5 className="mb-4">Contact</h5>
            <Formik
              initialValues={initialValues}
              validationSchema={validationSchema}
              // onSubmit={handleAddData}
              validateOnMount
            >
              {(formik) => (
                <Form className="w-100">
                    <FormikController
                      control="selectsearch"
                      options={city}
                      formik={formik}
                      name="whoYouAre"
                      label="Please Tell Us Who You Are"
                    />
                    <FormikController
                      control="input"
                      type="text"
                      name="email"
                      label="Email"
                    />
                    <FormikController
                     control="textarea"
                      name="message"
                      rows="8"
                      label="Message"
                    />
                    <div>
                      <Button variant="primary" type="submit">
                        Send
                      </Button>
                    </div>
                </Form>
              )}
            </Formik>
      </Container>
  );
};
export default Contact;

and here the resusable select that i used from ant design

import React from "react";
import { Form,Select } from "antd";
import { ErrorMessage } from "formik";
import TextError from "./TextError";
const { Option } = Select;
const SearchSel = (props) => {
const { label, name, options ,formik, ...rest } = props;
console.log(formik);
return (
  <Form.Item className="mb-3">
    <Select
      showSearch
      size="large"
      optionFilterProp="children"
      placeholder={label}
      name={name}
      onChange={(value) => formik.setFieldValue("whoYouAre", value)}
    >
      {options.map((option) => {
        return (
          <Option key={option.value} value={option.value}>
            {option.key}
          </Option>
        );
      })}
    </Select>
    <ErrorMessage name={name} component={TextError} />
  </Form.Item>
);

}; export default SearchSel;


Solution

  • Your default state is "" isn't right I believe. You probably want null.

    Secondly, your Select is not correctly bound to the form state. You need to add value.

    Moreover, you also need to add defaultActiveFirstOption={false} as that may be immediately selecting the first item on the initial state.

    Finally, and probably most importantly, probably need to bind the fields blur such that it sets the field as touched. ErrorMessage won't show the error unless it thinks the user touched the field:

    
        <Select
          showSearch
          size="large"
          optionFilterProp="children"
          placeholder={label}
          name={name}
          value={formik.values.whoYouAre}
          defaultActiveFirstOption={false}
          onChange={(value) => formik.setFieldValue("whoYouAre", value)}
          onBlur={() => formik.setFieldTouched("whoYouAre", true)}
        >