How to get error message by getFieldError in AntD Form? - reactjs

I'm validating form with Ant Design but I have a problem with getFieldError(). I need to get the error messages by the field name of Form.Item but it not works.
Here's my code not works below:
...
<Form form={form} name="login_form" onFinish={onFinish} scrollToFirstError>
<Form.Item
label="Password"
name="password"
rules={[
{
required: true,
message: 'Password cannot be empty!',
},
]}
help='' // hide validating message.
>
<>
{({ getFieldError }) => console.log(getFieldError('password'))}
//it not logging anything when submit form trigger error
<Input.Password placeholder="Enter your password" />
</>
</Form.Item>
</Form>
How can I solved this problem?

Your console.log will invoke, every time your component renders, so you need to rerender your component whenever validation applies on the form. To handle this situation you can use render prop with Form component, like this:
function CustomFormItem({ error, ...other }) {
console.log(error)
return <Input.Password placeholder="Enter your password" {...other} />;
}
function MyForm() {
const [form] = Form.useForm();
const onFinish = (values) => {
console.log(values);
};
return (
<Form
form={form}
name="login_form"
onFinish={onFinish}
scrollToFirstError
>
{(values,formInstance) => {
return (
<>
<Form.Item
label="Password"
name="password"
rules={[
{
required: true,
message: 'Password cannot be empty!',
},
]}
help="" // hide validating message.
>
<CustomFormItem error={formInstance.getFieldError('password')} />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</>
);
}}
</Form>
);
}
Consider that with above implementation, render prop will call with every change on the form.

Use can use getFieldError(); like the code example below
Function as Child Component is not working perfectly inside <Form.Item> component as of now.
<Form {...layout} form={form} name="control-hooks" onFinish={onFinish}>
{(values, formInstance) => {
console.log(formInstance.getFieldError("password")[0]);
return (
<>
<Form.Item
name="password"
label="Password"
rules={[
{
required: true
}
]}
>
<Input />
</Form.Item>
</>
);
}}
</Form>

Related

how to implement form for mapped child component

I have a parent component that has the root <Form>. The child component has another fields which needs to be validated. But the the child component is mapped from a data and once i try to change one field, it changes every fields.
Code:
<Form id="myForm" name="basic" onFinish={onSubmit}>
<Form.Item
name="title"
rules={[
{
required: true,
message: "Please input your title!"
}
]}
>
<Text editable>{title}</Text>
</Form.Item>
{data.map((d) => (
<SecForm />
))}
</Form>
Child Component:
const SecForm = () => {
return (
<>
<Form.Item
label="target"
name="target"
rules={[
{
required: true,
message: "Please input your target!"
}
]}
>
<Input placeholder="Target" />
</Form.Item>
</>
);
};
Tried giving ids to the mapped component, but still dint work.
Any simpler solution is apreciated.
Code sandbox link: https://codesandbox.io/s/basic-antd-4-16-9-forked-o8nxdl?file=/index.js
I believe this happens because <SecForm> sets the same name to all form items. Try to pass the data to that component, and change the name of the item based on it
const SecForm = ({ data }) => {
return (
<>
<Form.Item
label="target"
name={`target${data}`}
rules={[
{
required: true,
message: "Please input your target!"
}
]}
>
<Input placeholder="Target" />
</Form.Item>
</>
);
};

Display an error if the password and login are incorrect in Form. Antd React

The task is as follows, when you press the LOGIN button, a request is sent to the server with a password and login, if they are incorrect, then under the password entry line you need to display the corresponding error and all input fields should be highlighted in red.
How can you achieve this?
I tried to do it for a very long time using built-in validators in Form.Item . So, since I don't need to worry about changing the color of input fields, the validator does it itself, but I got confused about these validators and I got an infinite loop.
Here is some of the code for the Login page.
export const LoginPage = () => {
const { dispatch } = useAuthContext()
const onFinish = (values: any) => {
APIs.requestLogin(values.username, values.password, false)
.then((response: any) => {
dispatch({ type: SIGN_IN, payload: response.data })
})
.catch(() => {
console.log('error')
})
}
return (
<div className={classes.root}>
<div className={classes.container}>
<Form
className={classes.form_container}
name="normal_login"
initialValues={{ remember: true }}
onFinish={onFinish}
>
<Form.Item
className={classes.form_input}
name="username"
rules={[{ required: true, message: 'Please enter your username!' }]}
>
<Input
autoFocus={true}
className={classes.input_style}
placeholder="Username"
prefix={<UserOutlined className="site-form-item-icon" />}
/>
</Form.Item>
<Form.Item
className={classes.form_input}
name="password"
rules={[{ required: true, message: 'Please enter your password!' }]}
>
<Input.Password className={classes.input_style} placeholder="Password" prefix={<LockOutlined />} />
</Form.Item>
<Form.Item className={classes.form_submit}>
<Button className={classes.form_button_submit} type="primary" htmlType="submit">
LOGIN
</Button>
</Form.Item>
</Form>
<div className={classes.image} />
</div>
</div>
)
}

Ant Design v4. How to show the error message from custom validator in form

How to get the error message from the validator and show it in the form? I have 2 types of errors: "Please enter password" - if the field is empty and "Incorrect password" - when the password does not match. How to realize this?
export const LoginPage = ({ startLogin }) => (
<div>
<Form
name="normal_login"
initialValues={{ remember: true }}
onFinish={startLogin}
validateTrigger='onSubmit'
>
///////////////////////////////////THE CORE PART////////////////////////////////////////
<Form.Item
name="password"
rules={[{ required: true, message: 'Please enter password!' }, ({ getFieldValue }) => ({
//WHY THE MESSAGE ABOVE IS NOT SHOWN AT ALL?
validator(_, value) {
axios.get('users.json').then(({ data }) => {
if (condition) //do smth.
else if (condition) {
throw new Error("Incorrect password"); //<-- HOW TO SHOW THIS
}
});
}).catch(e => {console.log(e); return e});
},
}),]}
>
/////////////////////////////////////////////////////////////////////////////////////////
<Input.Password
className="input"
iconRender={visible => (visible ? <EyeTwoTone /> : <EyeInvisibleOutlined />)}
prefix={<LockOutlined className="site-form-item-icon" />}
type="password"
placeholder="Password"
/>
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" className="login-form-button">
Log in
</Button>
</Form.Item>
</Form>
</div>
);```

Antd form remote submit

I want to trigger the submit button outside the antd form
Here is my code
<Form
{...layout}
name="basic"
initialValues={{
remember: true,
}}
onFinish={onFinish}
onFinishFailed={onFinishFailed}
>
<Form.Item
label="Username"
name="username"
rules={[
{
required: true,
message: 'Please input your username!',
},
]}
>
<Input />
</Form.Item>
<Form.Item {...tailLayout}>
// Submit button here works well
</Form.Item>
</Form>
I want this outside form tag, please suggest
<Button type="primary" htmlType="submit">
Submit
</Button>
You can try this way:
const [form] = Form.useForm();
const handleFinish = (values) => {
console.log("values: ", values);
};
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<MyForm form={form} onFinish={handleFinish} />
<Button onClick={() => form.submit()}>Submit</Button>
</div>
);
export const MyForm = ({ form, onFinish }) => {
return (
<Form
form={form}
onFinish={onFinish}
initialValues={{ username: "John Doe" }}
>
<Form.Item name="username">
<Input />
</Form.Item>
</Form>
);
};
If the form and the button are not in the same component then it is hard to create same reference for the form in 2 different place. But I found an other easy way:
<Form id="myForm">...</>
...
<Button form="myForm" key="submit" htmlType="submit">
Submit
</Button>
This is the answer from this issue
write a custom function like this:
function handleSubmit(){
form.validateFields().then((values) => {
// do something with values
})
}
and call it from Button onClick. so you don't need Form onFinish props.
sorry i was searching and see this old question.
as in the comment you should use
const [form] = Form.useForm();
that's a lot of function you can use one of them is submit.
form.submit();
you can refer to document and search for useform:
https://ant.design/components/form/

Other validation message is triggering instead of my message when using Ant design getFieldDecorator

I am using Ant design and this is my form when I click on save I am getting this type of validation msg instead of red bordered Antd validation msg
I want validation error like this which is shown in AntD documents.
https://codesandbox.io/s/do52z
I have writter my function like this
<Form id="myForm" onSubmit={this.handleSubmit}>
<Form.Item label="Code">
<CustomInput
form={this.props.form}
type="text"
disabled={this.state.disableFields}
name="code"
id="code"
placeholder=""
required={true}
errorMsg={"Please input code!"}
/>
</Form.Item>
</Form>
This is my custom Input
const CustomInput = ({
form, id, name, placeholder, required, errorMsg, type, disabled,}: Props) => {
return form.getFieldDecorator(id, {
rules: [
{
required: required,
message: errorMsg
}
]
})(
<Input
type={type}
name={name}
id={id}
disabled={disabled}
placeholder={placeholder}
className={name === "code" ? "code-input" : "input-box"}
/>
);
};
export default CustomInput;
and this is my save button
<Button
className="save-btn"
htmlType="submit"
form="myForm"
>
Save
</Button>
I think I am missing something little here. Thanks in advance
Ant design input doesn't have required prop..
Required prop should be give inside form.item rules prop.
Since you have given reqired to input tag it will cause Chrome to display a prompt that the user to fill out the field.
Update based on comment
Move formitem tag inside custominput component and try again.
<Form id="myForm" onSubmit={this.handleSubmit}>
<CustomInput
form={this.props.form}
type="text"
disabled={this.state.disableFields}
name="code"
id="code"
placeholder=""
required={true}
errorMsg={"Please input code!"}
/>
</Form>
..
const CustomInput = ({
form, id, name, placeholder, required, errorMsg, type, disabled,}: Props) => {
return(
<Form.Item label="Code">
{form.getFieldDecorator(id, {
rules: [
{
required: required,
message: errorMsg
}
]
})(
<Input
type={type}
name={name}
id={id}
disabled={disabled}
placeholder={placeholder}
className={name === "code" ? "code-input" : "input-box"}
/>
)}
</Form.Item>
)
};

Resources