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.
The above is wrapper inside antd form and each of it is a Form.Item
.
I need show validation message like this,
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
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
Form.useForm
which create Form instance to maintain data store. With this we can easily get the current form state like values, errors etc.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.