最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

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

programmeradmin0浏览0评论

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

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

Share Improve this question edited Apr 22, 2022 at 12:59 James Z 12.3k10 gold badges27 silver badges47 bronze badges asked Apr 22, 2022 at 11:45 DevThimanDevThiman 1,1381 gold badge14 silver badges28 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 5

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 e 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.

it's hard to say and please don't leave unlike if it's not true. but when you pass validator method in your rules like below:

 validator: validateId 

acutely you reference your validator into your method and the data and state that use in this method get initial state from first and never update. for solving this instead of passing reference to validator pass it as arrow-function and also pass your idStatus stat as arguments of method. something like bellow

 validator: (rule, value) => validateId(rule, value, idStatus)

with this approach you force your application to run this method each time want check validator.

  useEffect(() => {

  form.validateFields(['schoolId']);

  }, [form.getFieldValue("schoolId")]);
发布评论

评论列表(0)

  1. 暂无评论