如何将 `final-form-calculate` 与 `final-form-array` 结合起来
How do I combine `final-form-calculate` with `final-form-array`
我有一个使用 react-final-form-array
的表格,以便有许多 "Attendees"。我希望每个 Attendee.Email 输入都进行网络查找,然后根据结果设置 Attendee.FirstName 和 Attendee.Surname。
我不确定如何用 final-form-calculate
装饰器来表达。具体来说,我不知道如何引用数组中的单个表单项。
这是我的开始:
const MyForm = props => {
const calculator = createDecorator(
{
field: 'Attendees.Email', // <-- this needs to happen for each Email
updates: {
// ... do some lookups and set FirstName and Surname based off database query
Attendees.FirstName: (email, allValues) =>
someLookup(email).FirstName
}
},
);
const submit = values => {
console.log(values);
};
return (<Form onSubmit={submit}
mutators={{
...arrayMutators,
}}
decorators={[calculator]}
render={({handleSubmit, pristine, invalid, mutators: {push, pop}}) => {
return (
<form onSubmit={handleSubmit}>
<fieldset>
<legend>Attendees</legend>
<div className="fieldset">
<p><Button bsStyle="primary" onClick={() => push('Attendees', undefined)}>
Add attendee
</Button></p>
<FieldArray name="Attendees">
{({fields}) =>
fields.map((name, index) => (
<div key={name}>
<label>Attendee #{index + 1} {index > 0 && <span
onClick={() => {
const attendee = fields.remove(index);
}}
style={{cursor: 'pointer'}}
role="img"
aria-label="delete">❌</span>}</label>
<Field
name={`${name}.Email`}
component={TextField}
label="Email address"
validate={required}
/>
<Field
name={`${name}.FirstName`}
component={TextField}
label="First name"
validate={required}
/>
<Field
name={`${name}.Surname`}
component={TextField}
label="Surname"
validate={required}
/>
</div>
))}
</FieldArray>
</div>
</fieldset>
<Button type="submit" bsStyle="primary"
disabled={invalid}>Next</Button>
</form>
);
}}
/>);
};
export default MyForm;
我花了点功夫,但实际上很简单 - 来自 the website i noticed they have it listed (but not clearly)
所以对于我的情况,我只是选择了名称并更改了文本的最后部分以反映我想要修改的对象 属性。
下面,我使用正则表达式匹配一个字段,然后替换名称值的最后部分以匹配不同的字段(存储在 fieldName 中),然后 return 一个包含我正在更改的新字段的数组和新值。
{
field: /fields\[\d+\]\.field\.text/, // when a field matching this pattern changes...
updates: (value, name, allValues) => {
console.log('Update called', value, name);
const fieldName = name.replace('.text', '.name');
return {
[fieldName]: value.replace(/\W+/gi, '-').toLowerCase()
};
}
}
我有一个使用 react-final-form-array
的表格,以便有许多 "Attendees"。我希望每个 Attendee.Email 输入都进行网络查找,然后根据结果设置 Attendee.FirstName 和 Attendee.Surname。
我不确定如何用 final-form-calculate
装饰器来表达。具体来说,我不知道如何引用数组中的单个表单项。
这是我的开始:
const MyForm = props => {
const calculator = createDecorator(
{
field: 'Attendees.Email', // <-- this needs to happen for each Email
updates: {
// ... do some lookups and set FirstName and Surname based off database query
Attendees.FirstName: (email, allValues) =>
someLookup(email).FirstName
}
},
);
const submit = values => {
console.log(values);
};
return (<Form onSubmit={submit}
mutators={{
...arrayMutators,
}}
decorators={[calculator]}
render={({handleSubmit, pristine, invalid, mutators: {push, pop}}) => {
return (
<form onSubmit={handleSubmit}>
<fieldset>
<legend>Attendees</legend>
<div className="fieldset">
<p><Button bsStyle="primary" onClick={() => push('Attendees', undefined)}>
Add attendee
</Button></p>
<FieldArray name="Attendees">
{({fields}) =>
fields.map((name, index) => (
<div key={name}>
<label>Attendee #{index + 1} {index > 0 && <span
onClick={() => {
const attendee = fields.remove(index);
}}
style={{cursor: 'pointer'}}
role="img"
aria-label="delete">❌</span>}</label>
<Field
name={`${name}.Email`}
component={TextField}
label="Email address"
validate={required}
/>
<Field
name={`${name}.FirstName`}
component={TextField}
label="First name"
validate={required}
/>
<Field
name={`${name}.Surname`}
component={TextField}
label="Surname"
validate={required}
/>
</div>
))}
</FieldArray>
</div>
</fieldset>
<Button type="submit" bsStyle="primary"
disabled={invalid}>Next</Button>
</form>
);
}}
/>);
};
export default MyForm;
我花了点功夫,但实际上很简单 - 来自 the website i noticed they have it listed (but not clearly)
所以对于我的情况,我只是选择了名称并更改了文本的最后部分以反映我想要修改的对象 属性。
下面,我使用正则表达式匹配一个字段,然后替换名称值的最后部分以匹配不同的字段(存储在 fieldName 中),然后 return 一个包含我正在更改的新字段的数组和新值。
{
field: /fields\[\d+\]\.field\.text/, // when a field matching this pattern changes...
updates: (value, name, allValues) => {
console.log('Update called', value, name);
const fieldName = name.replace('.text', '.name');
return {
[fieldName]: value.replace(/\W+/gi, '-').toLowerCase()
};
}
}