I am using formik
for the forms. In my form, I need to use the concept of FieldArray
and it's a nested one. I could not fill the nested forms with respective values. Here is how I have done
const Itinerary = ({ itineraries, push, remove }) => {
return (
<>
<Heading>Itinerary</Heading>
{itineraries && itineraries.length === 0 && (
<span
style={{
color: theme.color.primary,
padding: "0 10px",
cursor: "pointer"
}}
onClick={() => push({})}
>
+
</span>
)}
{itineraries &&
itineraries.length > 0 &&
itineraries.map((day, index) => {
return (
<React.Fragment key={index}>
<Row key={index} style={{ alignItems: "center" }}>
<Text>
How many
<DaysField
component={TextField}
name={`itineraries.${index}.days`}
placeholder="days"
normalize={val => val && parseInt(val)}
/>
of itinerary?
</Text>
{itineraries && itineraries.length - 1 === index && (
<>
<Button>
<Button.Round onClick={() => push({})}>+</Button.Round>
</Button>
<Button>
<Button.Round onClick={() => remove(index)}>
-
</Button.Round>
</Button>
</>
)}
</Row>
<FieldArray
name={`itineraries.${index}.itinerary`}
render={({ push, remove }) => (
<>
<Heading>
Fill up itinerary
{itineraries[index].itinerary &&
itineraries[index].itinerary.length === 0 && (
<span
style={{
color: theme.color.primary,
padding: "0 10px",
cursor: "pointer"
}}
onClick={() => push({})}
>
+
</span>
)}
</Heading>
{itineraries[index].itinerary &&
itineraries[index].itinerary.length > 0 &&
itineraries[index].itinerary.map((i, idx) => {
console.log(
"itinerary index",
itineraries[index].itinerary[idx]
);
return (
<React.Fragment>
<Row
style={{
alignItems: "center",
alignSelf: "center"
}}
>
<Col xs={12} md={3}>
<Field
component={TextField}
placeholder="Day"
name={`${itineraries[index].itinerary[idx]}.day`}
/>
</Col>
<Col xs={12} md={3}>
<Field
component={TextField}
placeholder="Description"
name={`${itineraries[index].itinerary[idx]}.description`}
/>
</Col>
<Col xs={12} md={3}>
<Field
component={TextField}
placeholder="Overnight"
name={`${itineraries[index].itinerary[idx]}.overnight`}
/>
</Col>
<Col xs={12} md={2}>
<Field
component={TextField}
placeholder="Altitude"
name={`${itineraries[index].itinerary}.altitude`}
normalize={value => {
return value && parseFloat(value);
}}
/>
</Col>
<Col xs={12} md={1}>
{itineraries &&
itineraries.length - 1 === index && (
<>
<ActionBtn>
<Button>
<Button.Round
onClick={() => push({})}
>
+
</Button.Round>
</Button>
<Button>
<Button.Round
onClick={() => remove(index)}
color={theme.color.red}
>
-
</Button.Round>
</Button>
</ActionBtn>
</>
)}
</Col>
</Row>
</React.Fragment>
);
})}
</>
)}
/>
</React.Fragment>
);
})}
</>
);
};
The itineraries initialValues looks like this
itineraries: [
{
days: 1,
itinerary: [
{
day: "Day 1",
description: "description",
overnight: "overnight info",
altitude: 150.5
},
{
day: "Day 2",
description: "description 2",
overnight: "overnight info",
altitude: 150.5
}
]
}
]
Only Nested part is not working. Can anyone help me at this, please?
You problem is in how you pass the name for the component
name={`${itineraries[index].itinerary[idx]}.overnight`}
This way, what you are doing is passing the value of itineraries[index].itinerary[idx]
to a string.
What you should do is pass that as a string, not it's value.
name={`itineraries[${index}].itinerary[${idx}]}.overnight`}
This way, only the indexs get the value printed, which is correct.
Here is the difference
${itineraries[index].itinerary[idx]}.overnight
will return [object Object].overnight
because you are access the value of itineraries[index].itinerary[idx]
and it's calling .toString()
.
But itineraries[${index}].itinerary[${idx}]}.overnight
will return itineraries[0].itinerary[0].overnight
which is a valid formik string and it can get it's value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With