Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validate antd form input in onChange with the value return by back-end API call

In my project I have antd form which used to add school details. In that form, I have ID field which need to be validated with back-end in onChange when input length = 5, whether that given ID is exists or not.

antd version 4.18.2

Field validations are handled via rules attribute in Form.item.

I use validator function to handle this custom validation.

State values

  const [idStatus, setIdStatus] = useState(false); // this value is get by API call.
  const [validateStatus, setValidateStatus] = useState("");

Form ID field

<Form form={form} name="form" onFinish={onFinish}>
    <Row className="applicationFormContent">
      <Col span={8}>
        <Form.Item
          name="schoolId"
          label="School Id"
          validateStatus={validateStatus}
          rules={[
            {
              required: true,
              message: "Please Provide School ID!"
            },
            {
              len: 5,
              message: "School ID must have 5 digits"
            },
            {
              validator: validateId // validator is a function used for custom validation.
            }
          ]}
        >
          <Input
            type={"number"}
            maxLength={5}
            placeholder="Id - 00000 format"
            onChange={(e) => checkSchoolId(e.target.value)}
          />
        </Form.Item>
      </Col>
    </Row>
  </Form>

Function triggered in onChange

const checkSchoolId = async (value) => {
try {
  if (value.length === 5) {
    let response = await checkId(value);
    console.log("-----", response.response?.data?.idExists);
    setIdStatus(response.response?.data?.idExists);
  } else {
    setValidateStatus("error");
  }
} catch (err) {
  console.log(err);
}
};

Validator function used in rules

const validateId = (rule, value) => {
if (idStatus) {
  // value return from API call.
  setValidateStatus("error");
  return Promise.reject("Census Id Already Exist");
} else {
  setValidateStatus("success");
  return Promise.resolve();
}
};

Problem:

when the input length = 5, I get the value from backend and it updates the state. But validator function is not triggered with that update. Which means Form input is not being re-rendered when update the state variable. i logged the values and updated values are shown as it is.

But when I type one more number (input-lenght=6), show both validations and then delete one character (now input-length=5), it shows the validation get from back-end value.

how to solve this?

example code sandbox

like image 279
DevThiman Avatar asked Oct 31 '25 00:10

DevThiman


1 Answers

There is a method named form.validateFields(['array of input names need to validate']) provided by antd Form for field validations.

With that I was able to re-execute the validation of the schoolId input when response come for idStatus inside a useEffect as below.

useEffect(() => {
// manually validate the field since input is not validated by form once state update.
form.validateFields(['schoolId']);
}, [idStatus]);

With the above way, we can manually trigger validation for particular Form.Item in antd Form wherever we want.

like image 199
DevThiman Avatar answered Nov 02 '25 13:11

DevThiman