Why the ant design select option doesnt save selected option? - reactjs

I have developed a project with context crud. Everything is fine, only the select option does not work, that is, after any option is selected and added, the selected option does not appear in the edit section. What is the problem ?
I have error this : 'Cannot read properties of undefined (reading 'name')'
import React, { useState } from "react";
import { useContext } from "react";
import { GlobalContext } from "../../context/GlobalState";
import { useNavigate } from "react-router-dom";
import { NavLink } from "react-router-dom";
import { v4 as uuidv4 } from "uuid";
import styles from "../ContactForm/Form.module.scss";
import { toast } from "react-toastify";
import { Checkbox, Button, Form, Input, Select, Radio } from "antd";
const Form1 = () => {
const { ADD_CONTACT } = useContext(GlobalContext);
const [contact, setContact] = useState({
id: uuidv4(),
name: "",
surname: "",
fatherName: "",
specialty: "",
email: "",
gender: "",
updatesNotification: "",
test: "",
});
const { Option } = Select;
const { name, surname, fatherName, specialty, email } = contact;
let history = useNavigate();
const onSubmit = () => {
if (contact) {
ADD_CONTACT(contact);
history("/contacts");
console.log(contact);
toast.success("Contact successfully added");
}
};
const selectOptions = [
{ label: "One", value: 1 },
{ label: "Two", value: 2 },
{ label: "Three", value: 3 },
];
return (
<>
<Form
onFinish={onSubmit}
className={styles.form}
name="myForm"
initialValues={{
remember: true,
}}
autoComplete="off"
labelCol={{
span: 2,
}}
wrapperCol={{
span: 16,
}}
>
<div className="row">
<Form.Item
label="Name"
rules={[{ required: true, message: "Please input your name!" }]}
>
<Input
placeholder="Enter Your Name"
value={name}
name="name"
onChange={(e) =>
setContact({ ...contact, [e.target.name]: e.target.value })
}
/>
</Form.Item>
</div>
<Form.Item
label="Surname"
rules={[{ required: true, message: "Please input your surname!" }]}
>
<Input
placeholder="Enter Your Surname"
value={surname}
name="surname"
onChange={(e) =>
setContact({ ...contact, [e.target.name]: e.target.value })
}
/>
</Form.Item>
<Form.Item
label="Father Name"
rules={[{ required: true, message: "Please input your surname!" }]}
>
<Input
placeholder="Enter Your FatherName"
value={fatherName}
name="fatherName"
onChange={(e) =>
setContact({ ...contact, [e.target.name]: e.target.value })
}
/>
</Form.Item>
<Form.Item
label="Email"
rules={[{ required: true, message: "Please input your mail!" }]}
>
<Input
name="email"
placeholder="your mail"
value={email}
onChange={(e) =>
setContact({ ...contact, [e.target.name]: e.target.value })
}
/>
</Form.Item>
<Form.Item
label="Specialty"
rules={[{ required: true, message: "Please input your specialty!" }]}
>
<Input
name="specialty"
placeholder="your specialt"
value={specialty}
onChange={(e) =>
setContact({ ...contact, [e.target.name]: e.target.value })
}
/>
</Form.Item>
<Form.Item label='Category'>
<Select
onChange={(e)=>setContact({ ...contact, [e.target.name]: e.target.value })}
defaultValue='category'
value={contact.test}
name="test"
style={{
width: 120,
}}
>
{selectOptions.map((item) => (
<Option key={item.value} value={item.value}></Option>
))}
</Select>
</Form.Item>
<Form.Item label="Gender">
<Radio.Group
onChange={(e) =>
setContact({
...contact,
[e.target.name]: e.target.checked ? e.target.id : "",
})
}
name="gender"
rules={[{ required: true, message: "Please your gender!" }]}
>
<Radio
id="female"
value="Female"
checked={contact.gender === "female"}
>
Female
</Radio>
<Radio id="male" value="Male" checked={contact.gender === "male"}>
Male
</Radio>
</Radio.Group>
</Form.Item>
<Form.Item>
<Checkbox
name="updatesNotification"
checked={contact.updatesNotification === "update"}
id="update"
onChange={(e) =>
setContact({
...contact,
[e.target.name]: e.target.checked ? e.target.id : "",
})
}
>
I want to be notified of updates
</Checkbox>
</Form.Item>
<div className={styles.buttons}>
<Button type="primary" htmlType="submit">
Add contact
</Button>
<NavLink to="/contacts">
<Button danger>Cancel</Button>
</NavLink>
</div>
</Form>
</>
);
};
export default Form1;

onChange Event in Antd Select only gives the Selected Value, it will not return any event
So Modifying your code into below will fix your issue..
<Select
onChange={(e)=>setContact({ ...contact, test : e })}
defaultValue='category'
value={contact.test}
name="test"
style={{
width: 120,
}}
>
{selectOptions.map((item) => (
<Option key={item.value} value={item.value}></Option>
))}
</Select>

Related

How prevent submit edit form when anything is not changed?

I have a form like this that I created with context crud project. Here I want that if no changes have been made in the form, it should not be updated and a notification should be issued. How can I do this?
Note: also, if any input is empty, do not submit. How can I do this without required the input. How can I fix these problems?
import React from "react";
import { NavLink } from "react-router-dom";
import { useContext, useState, useEffect } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { GlobalContext } from "../../context/GlobalState";
import styles from "../ContactForm/Form.module.scss";
import { toast } from "react-toastify";
const EditContactForm = () => {
const { contacts, UPDATE_CONTACT } = useContext(GlobalContext);
const [selectedContact, setSelectedContact] = useState({
id: "",
name: "",
surname: "",
fatherName: "",
specialty: "",
email: "",
gender: "",
test:''
});
const history = useNavigate();
const { id } = useParams();
useEffect(() => {
const userId = id;
const selectedContact = contacts.find((user) => String(user.id) === userId);
if (selectedContact) {
setSelectedContact(selectedContact);
}
}, [id, contacts]);
function onSubmit(e) {
e.preventDefault();
if(selectedContact){
UPDATE_CONTACT(selectedContact);
console.log("new user edited:", selectedContact);
history("/contacts");
toast('updated')
}
else if(selectedContact===contacts){
toast('anything doesnt changed') // problem is there
}
}
const handleOnChange = (e) => {
setSelectedContact((selectedContact) => ({
...selectedContact,
[e.target.name]: e.target.value,
}));
};
const inputHandleChange = (e) => {
setSelectedContact({
...selectedContact,
[e.target.name]: e.target.checked ? e.target.id : "",
});
};
const selectOptions = [
{ label: "One", value: 1 },
{ label: "Two", value: 2 },
{ label: "Three", value: 3 },
];
const onChange = (e) => setSelectedContact({ ...selectedContact, [e.target.name]: e.target.value })
return (
<div className={styles.form}>
<form onSubmit={onSubmit}>
<div class="mb-3 row row d-flex justify-content-around">
<label className={`col-sm-2 p-0 ${styles.inputLabel}`}>Name</label>
<div class="col-sm-8">
<input
class="form-control"
name="name"
required
value={selectedContact?.name ?? ""}
onChange={handleOnChange}
/>
</div>
</div>
<div class="mb-3 row row d-flex justify-content-around">
<label className={`col-sm-2 p-0 ${styles.inputLabel}`}>Surname</label>
<div class="col-sm-8">
<input
class="form-control"
name="surname"
required
value={selectedContact?.surname ?? ""}
onChange={handleOnChange}
/>
</div>
</div>
<div class="mb-3 row row d-flex justify-content-around">
<label className={`col-sm-2 p-0 ${styles.inputLabel}`}>
Father Name
</label>
<div class="col-sm-8">
<input
class="form-control"
name="fatherName"
required
value={selectedContact?.fatherName ?? ""}
onChange={handleOnChange}
/>
</div>
</div>
<div class="mb-3 row row d-flex justify-content-around">
<label className={`col-sm-2 p-0 ${styles.inputLabel}`}>Email</label>
<div class="col-sm-8">
<input
class="form-control"
name="email"
required
value={selectedContact?.email ?? ""}
onChange={handleOnChange}
/>
</div>
</div>
<div class="mb-3 row row d-flex justify-content-around">
<label className={`col-sm-2 p-0 ${styles.inputLabel}`}>
Specialty
</label>
<div class="col-sm-8">
<input
class="form-control"
name="specialty"
required
value={selectedContact?.specialty ?? ""}
onChange={handleOnChange}
/>
</div>
</div>
<div className="mb-3 row row d-flex justify-content-around">
<label className={`col-sm-2 p-0 ${styles.inputLabel}`}>position</label>
<div className="col-sm-8 d-flex justify-content-center align-items-center">
<select
onChange={onChange}
value={selectedContact.test}
name="test"
class="form-select"
aria-label="Default select example"
>
{selectOptions.map((item) => (
<option
key={item.value}
value={item.value}
>
{item.label}
</option>
))}
</select>
</div>
</div>
<div className="mb-3 row row d-flex justify-content-around">
<label className={`col-sm-2 p-0 ${styles.inputLabel}`}>Gender</label>
<div className="col-sm-8">
<div class="form-check form-check-inline ">
<input
class="form-check-input"
type="radio"
name="gender"
id="male"
checked={selectedContact.gender === "male"}
onChange={inputHandleChange}
/>
<label class="form-check-label">Male</label>
</div>
<div class="form-check form-check-inline">
<input
class="form-check-input"
type="radio"
name="gender"
id="female"
checked={selectedContact.gender === "female"}
onChange={inputHandleChange}
/>
<label class="form-check-label">Female</label>
</div>
</div>
</div>
<div className="mb-3 row d-flex justify-content-around">
<div class="form-check col-sm-11">
<input
class="form-check-input"
type="checkbox"
name="updatesNotification"
id="update"
checked={selectedContact.updatesNotification === "update"}
onChange={(e) =>
setSelectedContact({
...selectedContact,
[e.target.name]: e.target.checked ? e.target.id : "",
})
}
/>
<label class="form-check-label" for="flexCheckDefault">
I want to be notified of updates
</label>
</div>
</div>
<div className={styles.buttons}>
<button type="submit" class="btn btn-primary">
Update a contact
</button>
<NavLink to="/contacts" className="btn btn-danger m-2">
Cancel
</NavLink>
</div>
</form>
</div>
);
};
export default EditContactForm;
import React, { useState } from "react";
import { useContext } from "react";
import { GlobalContext } from "../../context/GlobalState";
import { useNavigate } from "react-router-dom";
import { NavLink } from "react-router-dom";
import { v4 as uuidv4 } from "uuid";
import styles from "../ContactForm/Form.module.scss";
import { toast } from "react-toastify";
import { Checkbox, Button, Form, Input, Select, Radio } from "antd";
const Form1 = () => {
const { ADD_CONTACT } = useContext(GlobalContext);
const [contact, setContact] = useState({
id: uuidv4(),
name: "",
surname: "",
fatherName: "",
specialty: "",
email: "",
gender: "",
updatesNotification: "",
test: "",
});
const { Option } = Select;
const { name, surname, fatherName, specialty, email } = contact;
let history = useNavigate();
const onSubmit = () => {
if (contact) {
ADD_CONTACT(contact);
history("/contacts");
console.log(contact);
toast.success("Contact successfully added");
}
else{
???
}
};
const selectOptions = [
{ label: "One", value: 1 },
{ label: "Two", value: 2 },
{ label: "Three", value: 3 },
];
return (
<>
<Form
onFinish={onSubmit}
className={styles.form}
name="myForm"
initialValues={{
remember: true,
}}
autoComplete="off"
labelCol={{
span: 2,
}}
wrapperCol={{
span: 16,
}}
>
<div className="row">
<Form.Item
label="Name"
rules={[{ required: true, message: "Please input your name!" }]}
>
<Input
placeholder="Enter Your Name"
value={name}
name="name"
onChange={(e) =>
setContact({ ...contact, [e.target.name]: e.target.value })
}
/>
</Form.Item>
</div>
<Form.Item
label="Surname"
rules={[{ required: true, message: "Please input your surname!" }]}
>
<Input
placeholder="Enter Your Surname"
value={surname}
name="surname"
onChange={(e) =>
setContact({ ...contact, [e.target.name]: e.target.value })
}
/>
</Form.Item>
<Form.Item
label="Father Name"
rules={[{ required: true, message: "Please input your surname!" }]}
>
<Input
placeholder="Enter Your FatherName"
value={fatherName}
name="fatherName"
onChange={(e) =>
setContact({ ...contact, [e.target.name]: e.target.value })
}
/>
</Form.Item>
<Form.Item
label="Email"
rules={[{ required: true, message: "Please input your mail!" }]}
>
<Input
name="email"
placeholder="your mail"
value={email}
onChange={(e) =>
setContact({ ...contact, [e.target.name]: e.target.value })
}
/>
</Form.Item>
<Form.Item
label="Specialty"
rules={[{ required: true, message: "Please input your specialty!" }]}
>
<Input
name="specialty"
placeholder="your specialt"
value={specialty}
onChange={(e) =>
setContact({ ...contact, [e.target.name]: e.target.value })
}
/>
</Form.Item>
<Form.Item label='Category'>
<Select
onChange={(e)=>setContact({ ...contact, test : e })}
defaultValue='category'
// value={contact.test}
name="test"
style={{
width: 120,
}}
>
{selectOptions.map((item) => (
<Option key={item.value} value={item.value}></Option>
))}
</Select>
</Form.Item>
<Form.Item label="Gender">
<Radio.Group
onChange={(e) =>
setContact({
...contact,
[e.target.name]: e.target.checked ? e.target.id : "",
})
}
name="gender"
rules={[{ required: true, message: "Please your gender!" }]}
>
<Radio
id="female"
value="Female"
checked={contact.gender === "female"}
>
Female
</Radio>
<Radio id="male" value="Male" checked={contact.gender === "male"}>
Male
</Radio>
</Radio.Group>
</Form.Item>
<Form.Item>
<Checkbox
name="updatesNotification"
checked={contact.updatesNotification === "update"}
id="update"
onChange={(e) =>
setContact({
...contact,
[e.target.name]: e.target.checked ? e.target.id : "",
})
}
>
I want to be notified of updates
</Checkbox>
</Form.Item>
<div className={styles.buttons}>
<Button type="primary" htmlType="submit">
Add contact
</Button>
<NavLink to="/contacts">
<Button danger>Cancel</Button>
</NavLink>
</div>
</Form>
</>
);
};
export default Form1;
enter image description here
One way to check if two objects are equal is to transform them into string.
JSON.stringify(selectedContact) === JSON.stringify(contacts.find((user) => user.id === selectedContact.id))
For checking if one if the data is empty one way is using the method some, this method send true if one the item in an array match the condition.
if (Object.keys(selectedContact).some(key => !selectedContact[key])) {
alert('There are missing information')
}

How do you get a nested value item in ant design

im quite new on reactJS and also ant design. right now im trying to get a value from a Form.List that i want to make it / render it as json nested data output.
my full code :
import { MinusCircleOutlined, PlusOutlined } from '#ant-design/icons';
import { Button, Form, Input, Space, DatePicker, Select } from 'antd';
import axios from 'axios'
import { useNavigate } from 'react-router-dom'
import Cookies from "js-cookies";
import moment from 'moment';
import 'moment/locale/zh-cn';
const Stockpickingnew = ({ title }) => {
const options = [
{
value: '1',
label: 'True',
},
{
value: '0',
label: 'False',
},
{
value: '7',
label: 'product_tmpl_id'
},
];
const Navigate = useNavigate()
const dateFormat = ['DD-MM-YYYY'];
//---------------------------------------------------------------------------------------------------------------
let headers = {
"Authorization": "Bearer " + Cookies.getItem('access_token')
}
const onFinish = (values) => {
console.log('Success:', values);
let stockpick = {
date: moment(values.date).format("DD-MM-YYYY"),
origin: values.origin,
picking_type_id: values.picking_type_id,
location_id: values.location_id,
location_dest_id: values.location_dest_id,
stock_move_ids: [{
demand: values.demand,
done: values.done,
product_uom: values.product_uom,
product_tmpl_id: values.product_tmpl_id,
}]
};
console.log(JSON.stringify(stockpick))
let params = JSON.stringify(stockpick)
axios.post('http://127.0.0.1:5000/api/stockpickings', params, { headers })
.then(() => {
Navigate('/')
})
.catch(error => {
if (error.response) {
console.log(error.response);
}
});
};
const onFinishFailed = (errorInfo) => {
console.log('Failed:', errorInfo);
};
//---------------------------------------------------------------------------------------------------------------
return (
<>
<div className='new'>
<div className="top">
<h1>{title}</h1>
</div>
<div className="bottom">
<div className="stockPicking">
<Form
name="stockPickings"
layout="vertical"
onFinish={onFinish}
onFinishFailed={onFinishFailed}
autoComplete="off"
>
<div className="left">
<Form.Item
label="Origin :"
name='origin'
>
<Select
options={options}
placeholder="Origin"
/>
</Form.Item>
<Form.Item
label="Picking Type :"
name='picking_type_id'
>
<Select
options={options}
placeholder="Picking Type"
/>
</Form.Item>
<Form.Item
label="Date :"
name='date'
>
<DatePicker
format={dateFormat}
onChange={(dateInMomentFormat, dateInStringFormat) => {
console.log(dateInStringFormat);
}}
/>
</Form.Item>
</div>
<div className="right">
<Form.Item
label="Location :"
name='location_id'
>
<Select
options={options}
placeholder="Location"
/>
</Form.Item>
<Form.Item
label="Destination :"
name='location_dest_id'
>
<Select
options={options}
placeholder="Destination"
/>
</Form.Item>
</div>
<div className="stockMove">
<Form.Item>
<Form.List name="stock_move_ids">
{(fields, { add, remove }) => (
<>
{fields.map((field) => (
<Space
key={field.key}
style={{
display: 'flex',
marginBottom: 8,
}}
align="baseline"
>
<Form.Item
{...field}
name={[field.name, 'demand']}
key={[field.key, 'demand']}
rules={[
{
required: true,
message: 'Missing Demand',
},
]}
>
<Input placeholder="Demand" />
</Form.Item>
<Form.Item
{...field}
name={[field.name, 'done']}
key={[field.key, 'done']}
>
<Select
options={options}
placeholder="Done"
/>
</Form.Item>
<Form.Item
{...field}
name={[field.name, 'product_uom']}
key={[field.key, 'product_uom']}
rules={[
{
required: true,
message: 'Missing product_uom',
},
]}
>
<Select
options={options}
placeholder="product_uom"
/>
</Form.Item>
<Form.Item
{...field}
name={[field.name, 'product_tmpl_id']}
key={[field.key, 'product_tmpl_id']}
rules={[
{
required: true,
message: 'Missing product_tmpl_id',
},
]}
>
<Select
options={options}
placeholder="product_tmpl_id"
/>
</Form.Item>
<MinusCircleOutlined onClick={() => remove(field.name)} />
</Space>
))}
<Form.Item>
<Button type="dashed" onClick={() => add()} block icon={<PlusOutlined />}>
Add field
</Button>
</Form.Item>
</>
)}
</Form.List>
</Form.Item>
</div>
<Form.Item>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</Form>
</div>
</div>
</div>
</>
)
}
export default Stockpickingnew
im sorry if it's really hard to read but basically, what i really want to do is my Form.List can get a value as nested data like :
stock_move_ids: [{
demand: values.demand,
done: values.done,
product_uom: values.product_uom,
product_tmpl_id: values.product_tmpl_id,
}]
my console.log (values) and console.log JSON.stringify(stockpick) do have different result as image below.
first one is from console.log values and the bottom one is from console.log stockpick
Screenshoot here
stock_move_ids values have 0th index you can access it like this.
let stockpick = {
date: moment(values.date).format("DD-MM-YYYY"),
origin: values.origin,
picking_type_id: values.picking_type_id,
location_id: values.location_id,
location_dest_id: values.location_dest_id,
stock_move_ids: [
{
demand: values?.stock_move_ids?.[0]?.demand,
done: values?.stock_move_ids?.[0]?.done,
product_uom: values?.stock_move_ids?.[0]?.product_uom,
product_tmpl_id: values?.stock_move_ids?.[0]?.product_tmpl_id,
},
],
};

How to Trim White Spaces from input field in ant-design form?

I have a form with ant design. I want to add a rule for each input field that the user can't enter spaces to fill the input. (spaces forbidden)
I try this method { transform: (value) => value.trim() }but it doesn't work.
I appreciate your help.
<>
<Form.Item
label={t("forms.inputs.Name.label")}
rules={[
{
required: true,
message: t("forms.inputs.Name.rules.required"),
},
{
min: 3,
message: t("forms.inputs.Name.rules.minLength"),
},
]}>
<Input />
</Form.Item>
<Form.Item
label={t("forms.inputs.job.label")}
rules={[
{
required: true,
message: t("forms.inputs.job.rules.required"),
},
]}>
<Input />
</Form.Item>
<Form.Item
label={t("forms.inputs.Company.label")}
rules={[
{
required: true,
message: t("forms.inputs.Company.rules.required"),
},
]}>
<Input placeholder={t("forms.inputs.currentCompany.placeholder")} />
</Form.Item>
</>
Just write a custom validation rule:
<Form.Item
label="Username"
name="username"
rules={[
{
required: true,
message: "Required"
},
{
validator: (_, value) =>
!value.includes(" ")
? Promise.resolve()
: Promise.reject(new Error("No spaces allowed"))
}
]}
>
<Input />
</Form.Item>
For email validation, you can use the following regex pattern:
<Form.Item
label="Email"
name="email"
rules={[
{
required: true,
message: "Required"
},
{
pattern: /([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|\"([]!#-[^-~ \t]|(\\[\t -~]))+\")#([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|\[[\t -Z^-~]*])/,
message: "Invalid email"
}
]}
normalize={(value, prevVal, prevVals) => value.trim()}
>
<Input />
</Form.Item>
DEMO
Instead of trimming onChange, do that in an onBlur callback:
formatInput = (event) => { const attribute = event.target.getAttribute('name') this.setState({ [attribute]: event.target.value.trim() }) }
or when you click enter
onKeyPress={(e) => {if (e.key === "Enter") {setValue(e.target.value.trim())} }}
you can do like this instead of using trim()
import React, { useState } from 'react';
import 'antd/dist/antd.css';
import { Form, Input } from 'antd';
const App = () => {
const [inputValue, setValue] = useState({input1: '', input2: '', input3: ''});
const onFinish = (values) => {
console.log('Success:', values);
};
const onFinishFailed = (errorInfo) => {
console.log('Failed:', errorInfo);
};
const handleOnChange = (e) => {
let {value} = e.target;
let data = {...inputValue};
if (value.length && value[0] === ' ') {
data[e.target.name] = '';
setValue(data);
return;
}
data[e.target.name] = value;
setValue(data);
}
return (
<Form
name="basic"
labelCol={{
span: 8,
}}
wrapperCol={{
span: 16,
}}
initialValues={{
remember: true,
}}
onFinish={onFinish}
onFinishFailed={onFinishFailed}
autoComplete="off"
>
<>
<Form.Item
label={t("forms.inputs.Name.label")}
rules={[
{
required: true,
message: t("forms.inputs.Name.rules.required"),
},
{
min: 3,
message: t("forms.inputs.Name.rules.minLength"),
},
]}>
<Input name="input1" value={inputValue.input1} onChange={handleOnChange} />
</Form.Item>
<Form.Item
label={t("forms.inputs.job.label")}
rules={[
{
required: true,
message: t("forms.inputs.job.rules.required"),
},
]}>
<Input name="input2" value={inputValue.input2} onChange={handleOnChange} />
</Form.Item>
<Form.Item
label={t("forms.inputs.Company.label")}
rules={[
{
required: true,
message: t("forms.inputs.Company.rules.required"),
},
]}>
<Input name="input3" value={inputValue.input3} onChange={handleOnChange} placeholder={t("forms.inputs.currentCompany.placeholder")} />
</Form.Item>
</>
</Form>
);
};
export default App;

Change date format in antd <DatePicker />

I'm submitting a form to send data to my API that receives date in the format of YYYY-MM-DD but by default the DatePicker component keeps adding extra characters of time to the end of the date, for example when I enter a date for my date of birth field the value is stored in the format below
{
"date_of_birth":"2003-02-03T13:32:49.543Z"
}
I would prefer it to be just
{
"date_of_birth":"2003-02-03"
}
below is the code for the form and its submit function
const Demo = () => {
const [visible, setVisible] = useState(false);
const [form] = Form.useForm();
const showUserModal = () => {
setVisible(true);
};
const hideUserModal = () => {
setVisible(false);
};
const onFinish = values => {
console.log(JSON.stringify(values))
const userToken = localStorage.getItem(AUTH_TOKEN)
IndividualService.setToken(userToken)
IndividualService.postIndividual(values).then(resp => {
console.log(resp)
message.success('successfully added details for Individual plan')
}).catch(error => {
message.error('Error occured, plase try again', error.message)
})
};
const customFormat = value => `custom format: ${value.format("YYYY-MM-DD")}`;
return (
<Card title='Enter Customer details for individual plan'>
<Row justify='center'>
<Col span={20}>
<Form.Provider
onFormFinish={(name, { values, forms }) => {
if (name === 'userForm') {
const { basicForm } = forms;
const dependants = basicForm.getFieldValue('dependants') || [];
basicForm.setFieldsValue({
dependants: [...dependants],
...values
});
setVisible(false);
}
}}
>
<Form {...layout} name="basicForm" onFinish={onFinish} size='small'>
<Form.Item
name="first_name"
label="First Name"
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
<Form.Item
name="other_names"
label="Other Names"
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
<Form.Item
name="gender"
label="Gender"
rules={[
{
required: true,
},
]}
>
<Select>
<Option value="MALE">male</Option>
<Option value="FEMALE">female</Option>
</Select>
</Form.Item>
<Form.Item
name="date_of_birth"
label="Date of Birth"
rules={[
{
required: true,
},
]}
>
<DatePicker format={customFormat} />
</Form.Item>
<Form.Item
name="blood_group"
label="Blood Group"
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
<Form.Item
name="residential_address"
label="Residential address"
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
<Form.Item
name="workplace_address"
label="Workplace address"
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
<Form.Item
name="additional_telephone_no"
label="Additional phone no."
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
<Form.Item
name="NIN"
label="NIN"
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
<Form.Item
name="next_of_kin_name"
label="Next of kin name"
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
<Form.Item
name="next_of_kin_telephone"
label="next of kin phone."
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
<Form.Item
name="next_of_kin_email"
label="next of kin email."
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
<Form.Item
name="dependants"
label="Dependants List"
shouldUpdate={(prevValues, curValues) => prevValues.dependants !== curValues.dependants}
>
{({ getFieldValue }) => {
const dependants = getFieldValue('dependants') || [];
return dependants.length ? (
<ul>
{dependants.map((d, index) => (
<li key={index} className="user">
<Avatar icon={<UserOutlined />} />
<p>{d.first_name} - {d.relationship}</p>
</li>
))}
</ul>
) : (
<Typography.Text className="ant-form-text" type="secondary">
( <SmileOutlined /> No dependant yet. )
</Typography.Text>
);
}}
</Form.Item>
<Form.Item {...tailLayout}>
<Button htmlType="submit" type="primary">
Submit
</Button>
<Button
htmlType="button"
style={{
marginLeft: 8,
}}
onClick={showUserModal}
>
Add User
</Button>
</Form.Item>
</Form>
<ModalForm visible={visible} onCancel={hideUserModal} />
</Form.Provider>
</Col>
</Row>
</Card>
);
};
You can add the prop format to get the input in custom format, as
<DatePicker
format="YYYY-MM-DD"
/>
This will display the date in the format YYYY-MM-DD in the date picker.
To convert this to the required format you may need to format it in the onFinish , as:
const onFinish = values => {
console.log(JSON.stringify(values))
const userToken = localStorage.getItem(AUTH_TOKEN)
IndividualService.setToken(userToken)
values["date_of_birth"] = moment(values.date_of_birth).format("YYYY-MM-DD")
IndividualService.postIndividual(values).then(resp => {
console.log(resp)
message.success('successfully added details for Individual plan')
}).catch(error => {
message.error('Error occured, plase try again', error.message)
})
};

antd form field is not resetting for checkboxes

I have a antd form that consists of input and checkboxes.
antd : 4.16.0
react : 17.0.2
After using,
this.formRef.current.resetFields();
the input fields are getting reset but not the checkboxes.
Sample Code:
<Form
layout="vertical"
hideRequiredMark
initialValues={{
sunH: [
moment("00:00", "HH:mm"),
moment("00:00", "HH:mm"),
],
monH: [
moment("00:00", "HH:mm"),
moment("00:00", "HH:mm"),
],
}}
ref={this.props.formRef}
>
<Row gutter={16}>
<Col span={12}>
<Form.Item
name="pName"
label="Name"
rules={[
{
required: true,
message: "Please enter Name",
},
]}
>
<Input placeholder="Enter name" />
</Form.Item>
<Form.Item name="Mon" label="" valuePropName="checked">
<Text>Mon</Text>
</Form.Item>
</Col>
</Row>
</Form>
the form takes in a onCancel props, so onCancel,
this.formRef.current.resetFields();
log of this.formRef.current:
you can manually set radio fields value null in that function ...
all you have to do is ...
formRef.setFieldsValue(['label_name(Mon)'] : undefined)
try formRef.current.setFieldsValue if you cant't change using upper code.
for functional component you have to take the form reference that is binding using useForm() and you have to call setfield method same.
form.setFieldsValue(['label_name(Mon)'] : undefined )
ant.design/components/form/#components-form-demo-nest-messages Check the second example, they have well explained everything you need there
https://codesandbox.io/s/form-methods-antd-4-17-0-alpha-7-forked-ff1uf?file=/index.js:0-2953
Check this working example with checkbox
import React from "react";
import ReactDOM from "react-dom";
import "antd/dist/antd.css";
import "./index.css";
import { Form, Input, Button, Select, Checkbox } from "antd";
const { Option } = Select;
const layout = {
labelCol: {
span: 8
},
wrapperCol: {
span: 16
}
};
const tailLayout = {
wrapperCol: {
offset: 8,
span: 16
}
};
const Demo = () => {
const [form] = Form.useForm();
const onGenderChange = (value) => {
switch (value) {
case "male":
form.setFieldsValue({
note: "Hi, man!"
});
return;
case "female":
form.setFieldsValue({
note: "Hi, lady!"
});
return;
case "other":
form.setFieldsValue({
note: "Hi there!"
});
}
};
const onFinish = (values) => {
console.log(values);
};
const onReset = () => {
form.resetFields();
};
const onFill = () => {
form.setFieldsValue({
note: "Hello world!",
gender: "male"
});
};
return (
<Form {...layout} form={form} name="control-hooks" onFinish={onFinish}>
<Form.Item
name="note"
label="Note"
rules={[
{
required: true
}
]}
>
<Input />
</Form.Item>
<Form.Item
name="gender"
label="Gender"
rules={[
{
required: true
}
]}
>
<Select
placeholder="Select a option and change input text above"
onChange={onGenderChange}
allowClear
>
<Option value="male">male</Option>
<Option value="female">female</Option>
<Option value="other">other</Option>
</Select>
</Form.Item>
<Form.Item
noStyle
shouldUpdate={(prevValues, currentValues) =>
prevValues.gender !== currentValues.gender
}
>
{({ getFieldValue }) =>
getFieldValue("gender") === "other" ? (
<Form.Item
name="customizeGender"
label="Customize Gender"
rules={[
{
required: true
}
]}
>
<Input />
</Form.Item>
) : null
}
</Form.Item>
<Form.Item
name="remember"
valuePropName="checked"
wrapperCol={{
offset: 8,
span: 16
}}
>
<Checkbox>Remember me</Checkbox>
</Form.Item>
<Form.Item {...tailLayout}>
<Button type="primary" htmlType="submit">
Submit
</Button>
<Button htmlType="button" onClick={onReset}>
Reset
</Button>
<Button type="link" htmlType="button" onClick={onFill}>
Fill form
</Button>
</Form.Item>
</Form>
);
};

Resources