Home > Blockchain >  how to validate if one number is greater than other inside form rule?
how to validate if one number is greater than other inside form rule?

Time:06-15

Form contains two items, both of it is an input field that accepts a number. I need to check if the value entered in the first input (start) is always less than the second (end) or else, show a validation error.

UI

The above is wrapper inside antd form and each of it is a Form.Item. I need show validation message like this,

Validation error expected

Code:

const App = () => {
  const [start, setStart] = useState(1);
  const [end, setEnd] = useState(2);
  const formRef = useRef();

  const handleSubmit = () => {
    if (end < start) {
      console.log("End cannot be lesser than start");
    } else if (end === start) {
      console.log("End cannot be same as start");
    } else {
      console.log("Added :)", start, end);
    }
  };

  return (
    <Form
      onFinish={handleSubmit}
      layout="vertical"
      ref={formRef}
      requiredMark={false}
    >
      <div>
        <Form.Item
          name="formStart"
          rules={[
            {
              required: true,
              message: "Please select a form start"
            }
          ]}
        >
          <InputNumber
            placeholder="Start"
            min={1}
            max={100}
            onChange={(e) => setStart(e)}
          />
        </Form.Item>
        <Form.Item
          name="formEnd"
          rules={[
            {
              required: true,
              message: "Please select a form end"
            }
          ]}
        >
          <InputNumber
            placeholder="End"
            min={1}
            max={100}
            onChange={(e) => setEnd(e)}
          />
        </Form.Item>
        <Form.Item>
          <button htmlType="submit">Submit</button>
        </Form.Item>
      </div>
    </Form>
  );
};

If there is an alternative instead of using setState, It can also use ref (formRef.current)

Code sandbox: https://codesandbox.io/s/basic-usage-antd-4-21-0-forked-4sri66?file=/demo.js

CodePudding user response:

You can use useRef:

import React, { useRef } from "react";

Define ref variables:

const start = useRef();
const end = useRef();

Pass the refs to the inputs:

<InputNumber placeholder="Start" min={1} max={100} ref={start} />
<InputNumber placeholder="End" min={1} max={100} ref={end} />

Access the input values:

if (end.current.value < start.current.value) {
    // some code
}

You can also set the default values by adding the defaultValue attribute. For example:

<InputNumber placeholder="Start" min={1} max={100} ref={start} defaultValue={1} />

CodePudding user response:

For custom validations or conditional validations we need to include 'validator' inside our rules as below as per the antd docs.

<Form.Item
      name="formEnd"
      rules={[
        {
          required: true,
          message: "Please select a form end"
        },
        ({ getFieldValue }) => ({
          validator(rule, value) {
            // from 'getFieldValue("fieldName")' we can get the current value of that field.
            if (value < getFieldValue("formStart")) {
              // value = currentValue of this field. with that we can do validations with other values in form fields
              return Promise.reject("End range must be greater than start"); // The validator should always return a promise on both success and error
            } else if (value === getFieldValue("formStart")) {
              return Promise.reject("End cannot be same as start");
            } else {
              return Promise.resolve();
            }
          }
        })
      ]}
    >

With this approach, you can achieve above validation without use of internal state and also without useRef.

Few points for when use antd form

  1. antd form has Form.useForm which create Form instance to maintain data store. With this we can easily get the current form state like values, errors etc.
  2. It also has form.submit() function which trigger the given function for Form onFinish. So we can use that for SUBMIT Btn onClick.

Here is the full demo code in codesandbox.

Check this form/API for more antd Form props and functions.

  • Related