Sergei Klinov
Sergei Klinov

Reputation: 798

Antd Custom validator and validateFields are not working together as expected

I'm working on a form (Ant Design <Form>) where I want a custom validation of phone number (as it depends on country field and has some extra logic), and other fields validated by antd built-in features, so when user submits the form I want all fields to be validated with validateFields() passed as an array of field names showing validation errors as usual (red message underneath and an error message in console), but all I'm getting is just a warning message in the console.

Here's a minimal reproduction

Edit confident-goodall-4f0bx

Am I missing something about how validator function works?

Upvotes: 0

Views: 24302

Answers (3)

Sourav Singh
Sourav Singh

Reputation: 955

Here how I handled the error in antd form

import React, { useState } from 'react';
import { Form, Input } from 'antd';

function MyCustomForm(props: any) {
  const [form] = Form.useForm();
  const [validateFieldsName, setValidateFieldsName] = useState<string[]>([]);

  const handleValidateFieldNames = (name: string) => {
    const isFieldName = validateFieldsName.find(
      (fieldName) => fieldName === name
    );
    if (isFieldName) return 'onChange';
    return 'onBlur';
  };

  return (
    <Form form={form} layout="vertical">
      <Form.Item
        name="contactNumber"
        label="Contact Number"
        validateTrigger={handleValidateFieldNames('contactNumber')}
        rules={[
          {
            required: true,
            message: 'Please enter contact number!',
          },
          {
            validator(_, value) {
              if (!value || value.length === 10) {
                return Promise.resolve();
              }
              return Promise.reject('Please enter 10 digit Number!');
            },
          },
        ]}
      >
        <Input
          type="number"
          placeholder="Contact number"
          onBlur={() =>
            setValidateFieldsName([...validateFieldsName, 'contactNumber'])
          }
        />
      </Form.Item>
    </Form>
  );
}

export default MyCustomForm;

Upvotes: 1

Shafaat Akhunzada
Shafaat Akhunzada

Reputation: 66

make a if else check in your validatePhone function if value is not empty then run your code and if value is empty simply send a callback in else condition. like that

const validatePhone = (rule: any, value: any, callback: any) => {
  if (value) {
    const countryName = form.getFieldValue('country');
    const country = CountryList.getCode(countryName);
    const phoneNumber = parsePhoneNumberFromString(value, country as CountryCode);
    console.log(form.getFieldValue('country'));
    if (countryName && phoneNumber && phoneNumber.isValid()) {
      updatePhonePrefix(prefix.concat(phoneNumber.countryCallingCode as string));
      callback();
    } else {
      callback(`Phone number is not valid for ${countryName}`);
    }
  } else {
    callback();
  }
};

Upvotes: 5

Lawrence Chang
Lawrence Chang

Reputation: 449

what the antd docs recommend is to use async or try-catch block

option 1:

const validatePhone = async (rule, value) => {
  // check failing condition
  throw new Error('Something wrong!');
}

option 2:

const validatePhone = (rule, value, callback) => {
  try {
    throw new Error('Something wrong!');
  } catch (err) {
    callback(err);
  }
}

Upvotes: 1

Related Questions