Reputation: 385
I have a form made with formik, in which one of the information entered is the contact, however the user can have more than one contact.
I want to add a button that when clicking, new fields for entering more contacts appear. I've tried some logic, but to no avail
const { getFieldProps, touched, errors, isValid, handleSubmit } = useFormik({
initialValues: {
phone_name: '',
phone_ddd: '',
phone_number: '',
phone_observation: ''
},
onSubmit: (values, actions) => {
saveOrganization({
variables: {
name: values.phone_name,
ddd: values.phone_ddd,
number: values.phone_number,
observation: values.phone_observation,
}
})
})
return (
<TextField
margin="dense"
id="phone_name"
label={<IntlMessages id="name" />}
fullWidth
{...getFieldProps("phone_name")}
/>
{touched.phone_name && errors.phone_name ? (
<small>{errors.phone_name}</small>
) : null}
<InputMask
mask="99"
disabled={false}
maskChar=" "
{...getFieldProps("phone_ddd")}
>
{() =>
<TextField
label={<IntlMessages id='ddd' />}
fullWidth
{...getFieldProps("phone_ddd")}
/>
}
</InputMask>
{touched.phone_ddd && errors.phone_ddd ? (
<small>{errors.phone_ddd}</small>
) : null}
<InputMask
mask="999999999"
disabled={false}
maskChar=" "
{...getFieldProps("phone_number")}
>
{() =>
<TextField
label={<IntlMessages id='number' />}
fullWidth
{...getFieldProps("phone_number")}
/>
}
</InputMask>
{touched.phone_number && errors.phone_number ? (
<small>{errors.phone_number}</small>
) : null}
I want to add a button and new inputs appear
Upvotes: 1
Views: 1814
Reputation: 238
This is my approach. First I declare initialValues to have field 'contact' as array like this
useFormik({
initialValues: {
contact: [
{
name: "",
age: "",
},
],
},
});
Then I create a function for adding new field
const handleNewField = () => {
formik.setFieldValue("contact", [
...formik.values.contact,
{ name: "", age: "" },
]);
};
And in the render just map it out from array like this
<form onSubmit={formik.handleSubmit}>
{formik.values.contact.map((contact, index) => (
<div key={index}>
<label>Name</label>
<input {...formik.getFieldProps(`contact[${index}].name`)} />
<label>Age</label>
<input {...formik.getFieldProps(`contact[${index}].age`)} />
</div>
))}
<button type="submit">Submit</button>
<button type="button" onClick={handleNewField}>
New Field
</button>
</form>
I have try this and this is work just fine for me. If you have any question feel free to ask me I'll try my best to answer
Final code look like this
import React from "react";
import { useFormik } from "formik";
function App() {
const formik = useFormik({
initialValues: {
contact: [
{
name: "",
age: "",
},
],
},
onSubmit: (values) => {
console.log(values);
},
});
const handleNewField = () => {
formik.setFieldValue("contact", [
...formik.values.contact,
{ name: "", age: "" },
]);
};
return (
<div>
<form onSubmit={formik.handleSubmit}>
{formik.values.contact.map((contact, index) => (
<div key={index}>
<label>Name</label>
<input {...formik.getFieldProps(`contact[${index}].name`)} />
<label>Age</label>
<input {...formik.getFieldProps(`contact[${index}].age`)} />
</div>
))}
<button type="submit">Submit</button>
<button type="button" onClick={handleNewField}>
New Field
</button>
</form>
</div>
);
}
export default App;
Upvotes: 3