This is an example of a nested Field form.
The name
attribute of the nested Field must be expressed in dot notation.
Example: foo.bar
Validation on objects in the array can be specified using a wildcard (*
)!
Example: array.*.key
And, Dynamic data manipulation is possible by adding, deleting, or moving values using fields
.
{
"teams": [
{
"name": "Initial Team",
"scope": "private",
"members": []
}
]
}
import React from 'react';
import { dripForm } from 'react-drip-form';
const NestFieldsForm = dripForm({
validations: {
'teams.*.name': {
required: true,
max: 30,
},
'teams.*.members.*': {
max: 30,
},
},
})(({
handlers,
fields,
meta: { invalid, pristine },
}) => (
<form onSubmit={handlers.onSubmit}>
{fields.map('teams.*', (teamName, teamIndex) => (
<div key={teamName}>
<label htmlFor={teamName}>Team name #{teamIndex + 1}</label>
<Input
type="text"
name={`${teamName}.name`}
label="Team name"
/>
<div>
<FieldGroup name={`${teamName}.scope`}>
<Radio value="private">Private</Radio>
<Radio value="public">Public</Radio>
</FieldGroup>
<div className="members">
{fields.map(`${teamName}.members.*`, memberName => (
<div key={memberName}>
<label>Member name</label>
<div className="input-group">
<Input
type="text"
name={memberName}
label="Member name"
/>
<Button
small
type="button"
onClick={() => fields.remove(memberName)}
>
Delete
</Button>
</div>
</div>
))}
</div>
<Button
small
type="button"
onClick={() => fields.push(`${teamName}.members`, '')}
>
Add member
</Button>
{' '}
<Button
small
type="button"
onClick={() => fields.remove(teamName)}
>
Delete
</Button>
</div>
</div>
))}
<div>
<Button
type="button"
onClick={() => fields.push('teams', {
name: '',
scope: 'private',
members: [],
})}
>
Add team
</Button>
</div>
<div>
<Button
primary
onClick={handlers.onSubmit}
disabled={invalid || pristine}
>
Send message
</Button>
</div>
</form>
));