Redux 表单:具有多个提交按钮的条件表单验证
Redux Form: Conditional form validations with multiple submit buttons
我正在使用带有多个提交按钮的 Redux 表单以及 redux-form <Field />
。我需要根据这些按钮的点击来控制这些字段的验证。对于前。我需要根据点击这些按钮将标志设置为 True/False,以便我可以有条件地验证我的字段,如下所示:
<Field
name="date"
component={DateFormField}
validate={isSaveDraft && [validateRequiredText]}
floatingLabelText="Date"
fullWidth
helpText="blablabla"
/>
<Field
name="title"
component={TextFormField}
normalizeOnBlur={normalizeTextOnBlur}
validate={!isSaveDraft && [validateRequiredText]}
floatingLabelText="Project title"
fullWidth
helpText="blablabla"
/>
正如您从上面的代码中看到的,我正在使用 validate={isSaveDraft && [validateRequiredText]} 和 validate={! isSaveDraft && [validateRequiredText]}
这是我的两个提交按钮:
<RaisedButton
label={submitting ? 'Saving Draft...' : 'Save Draft'}
type="button"
onClick={handleSubmit(values => onSubmit())}
disabled={submitting}
primary
/>
<RaisedButton
label={submitting ? 'Submitting Brief...' : 'Submit Brief'}
type="button"
onClick={handleSubmit(values => onSubmit())}
disabled={submitting}
primary
/>
但是,我无法实现它。请帮忙。
将状态变量用作 isSaveDraft 并将其默认设置为 false
添加按钮的 onClick 动作以设置 state.isSaveDraft = true
validate={(isSaveDraft && [validateRequiredText]}
将不起作用,因为 validate
一直需要一个函数。此外,字段级验证发生在 Touch 或 onBlur 等上。这太早了,因为您不知道将单击哪个按钮。
您需要做的是使用一个额外的标志属性来保存单击了哪个按钮,然后在表单级别验证中使用它。
因此您的字段将如下所示(不再进行字段级别验证):
<Field
name="date"
component={DateFormField}
floatingLabelText="Date"
fullWidth
helpText="blablabla"
/>
...
<RaisedButton
label={submitting ? 'Saving Draft...' : 'Save Draft'}
onMouseDown={() => this.setDraftFlag(true)}
...
/>
<RaisedButton
label={submitting ? 'Submitting Brief...' : 'Submit Brief'}
onMouseDown={() => this.setDraftFlag(false)}
...
/>
我正在使用 onMouseDown
来捕获标志,因为您已经在使用 onClick
来提交表单。此外,无论如何我们都需要在提交之前进行验证。
然后在您的表单中 validate
(基于 SyncValidation example)
const validate = values => {
const errors = {}
const {isDraft, ...rest} = values
if(isDraft) {
// draft validations
} else {
// other validations
}
return errors
}
export default reduxForm({
form: 'myForm', // a unique identifier for this form
validate, // <--- validation function given to redux-form
})(MyForm)
setDraftFlag
可以是一个 action 或者你可以像这样让它成为你的表单组件的一部分(我发现这更容易,因为你已经将 change
绑定到你的表单):
setDraftFlag(value) {
this.props.change('isDraft', value));
}
经过大量的头痛和挠头之后,我终于找到了解决方案,而且不会让事情变得难看。感谢此解决方案的开发人员。最初的想法是在单击按钮时设置一个标志并有条件地验证字段。 (PS:我正在使用字段级验证)。然而,问题是验证是在标志设置之前执行的,因为在修复所有验证之前不会触发 onClick 处理程序,并且该逻辑深埋在 redux-forms 中(通过使用库使简单的事情不必要地过度复杂化的好处) ).
解决方法如下:
提交处理程序
handleSubmit() {
const { bookingCreate, modalShow, navigateTo } = this.props;
const { isDraftAction } = this.state; // my flag
// create record!
return bookingCreate(isDraftAction)
.then(responsePayload => {
...
})
.catch(handleSubmissionError);
}
isDraftAction
是在两个按钮的 onClick
上调用操作时设置 (in local state)
的标志。
我的条件字段级别验证
<Field
name="date"
component={DateFormField}
validate={isDraftAction && [validateRequiredText]}
fullWidth
helpText="blablabla"
/>
<Field
name="title"
component={TextFormField}
normalizeOnBlur={normalizeTextOnBlur}
validate={!isDraftAction && [validateRequiredText]}
fullWidth
helpText="blablabla"
/>
我的 SAVE RECORD 和 SUBMIT RECORD 两个按钮。
const submit = handleSubmit(values => onSubmit()); // this is redux-form's submit handler which will in-turn call my own submit handler defined above. (That's where the library hides all the logic and makes developer helpless)
<RaisedButton
label={submitting && isDraft ? 'Saving Draft...' : 'Save Draft'}
type="button"
onClick={() => {
this.props.dispatchAction({ draftAction: true }).then(() => {
submit();
});
}}
disabled={submitting}
primary
/>
<RaisedButton
label={submitting && !isDraft ? 'Submitting Brief...' : 'Submit Brief'}
type="button"
onClick={() => {
this.props.dispatchAction({ draftAction: false }).then(() => {
submit();
});
}}
disabled={submitting}
primary
/>
dispatchAction()
是我的操作函数,它将首先将标志设置为 true/false 然后调用 redux-forms 内置提交处理程序。此外,我已经提取了 redux-form 的提交处理程序,因为它只是为了更清楚。
dispatchAction()
dispatchAction={({ draftAction }) =>
new Promise(resolve => {
this.setState({ isDraftAction: draftAction }, resolve);
})
}
我正在使用带有多个提交按钮的 Redux 表单以及 redux-form <Field />
。我需要根据这些按钮的点击来控制这些字段的验证。对于前。我需要根据点击这些按钮将标志设置为 True/False,以便我可以有条件地验证我的字段,如下所示:
<Field
name="date"
component={DateFormField}
validate={isSaveDraft && [validateRequiredText]}
floatingLabelText="Date"
fullWidth
helpText="blablabla"
/>
<Field
name="title"
component={TextFormField}
normalizeOnBlur={normalizeTextOnBlur}
validate={!isSaveDraft && [validateRequiredText]}
floatingLabelText="Project title"
fullWidth
helpText="blablabla"
/>
正如您从上面的代码中看到的,我正在使用 validate={isSaveDraft && [validateRequiredText]} 和 validate={! isSaveDraft && [validateRequiredText]}
这是我的两个提交按钮:
<RaisedButton
label={submitting ? 'Saving Draft...' : 'Save Draft'}
type="button"
onClick={handleSubmit(values => onSubmit())}
disabled={submitting}
primary
/>
<RaisedButton
label={submitting ? 'Submitting Brief...' : 'Submit Brief'}
type="button"
onClick={handleSubmit(values => onSubmit())}
disabled={submitting}
primary
/>
但是,我无法实现它。请帮忙。
将状态变量用作 isSaveDraft 并将其默认设置为 false 添加按钮的 onClick 动作以设置 state.isSaveDraft = true
validate={(isSaveDraft && [validateRequiredText]}
将不起作用,因为 validate
一直需要一个函数。此外,字段级验证发生在 Touch 或 onBlur 等上。这太早了,因为您不知道将单击哪个按钮。
您需要做的是使用一个额外的标志属性来保存单击了哪个按钮,然后在表单级别验证中使用它。
因此您的字段将如下所示(不再进行字段级别验证):
<Field
name="date"
component={DateFormField}
floatingLabelText="Date"
fullWidth
helpText="blablabla"
/>
...
<RaisedButton
label={submitting ? 'Saving Draft...' : 'Save Draft'}
onMouseDown={() => this.setDraftFlag(true)}
...
/>
<RaisedButton
label={submitting ? 'Submitting Brief...' : 'Submit Brief'}
onMouseDown={() => this.setDraftFlag(false)}
...
/>
我正在使用 onMouseDown
来捕获标志,因为您已经在使用 onClick
来提交表单。此外,无论如何我们都需要在提交之前进行验证。
然后在您的表单中 validate
(基于 SyncValidation example)
const validate = values => {
const errors = {}
const {isDraft, ...rest} = values
if(isDraft) {
// draft validations
} else {
// other validations
}
return errors
}
export default reduxForm({
form: 'myForm', // a unique identifier for this form
validate, // <--- validation function given to redux-form
})(MyForm)
setDraftFlag
可以是一个 action 或者你可以像这样让它成为你的表单组件的一部分(我发现这更容易,因为你已经将 change
绑定到你的表单):
setDraftFlag(value) {
this.props.change('isDraft', value));
}
经过大量的头痛和挠头之后,我终于找到了解决方案,而且不会让事情变得难看。感谢此解决方案的开发人员。最初的想法是在单击按钮时设置一个标志并有条件地验证字段。 (PS:我正在使用字段级验证)。然而,问题是验证是在标志设置之前执行的,因为在修复所有验证之前不会触发 onClick 处理程序,并且该逻辑深埋在 redux-forms 中(通过使用库使简单的事情不必要地过度复杂化的好处) ).
解决方法如下:
提交处理程序
handleSubmit() {
const { bookingCreate, modalShow, navigateTo } = this.props;
const { isDraftAction } = this.state; // my flag
// create record!
return bookingCreate(isDraftAction)
.then(responsePayload => {
...
})
.catch(handleSubmissionError);
}
isDraftAction
是在两个按钮的 onClick
上调用操作时设置 (in local state)
的标志。
我的条件字段级别验证
<Field
name="date"
component={DateFormField}
validate={isDraftAction && [validateRequiredText]}
fullWidth
helpText="blablabla"
/>
<Field
name="title"
component={TextFormField}
normalizeOnBlur={normalizeTextOnBlur}
validate={!isDraftAction && [validateRequiredText]}
fullWidth
helpText="blablabla"
/>
我的 SAVE RECORD 和 SUBMIT RECORD 两个按钮。
const submit = handleSubmit(values => onSubmit()); // this is redux-form's submit handler which will in-turn call my own submit handler defined above. (That's where the library hides all the logic and makes developer helpless)
<RaisedButton
label={submitting && isDraft ? 'Saving Draft...' : 'Save Draft'}
type="button"
onClick={() => {
this.props.dispatchAction({ draftAction: true }).then(() => {
submit();
});
}}
disabled={submitting}
primary
/>
<RaisedButton
label={submitting && !isDraft ? 'Submitting Brief...' : 'Submit Brief'}
type="button"
onClick={() => {
this.props.dispatchAction({ draftAction: false }).then(() => {
submit();
});
}}
disabled={submitting}
primary
/>
dispatchAction()
是我的操作函数,它将首先将标志设置为 true/false 然后调用 redux-forms 内置提交处理程序。此外,我已经提取了 redux-form 的提交处理程序,因为它只是为了更清楚。
dispatchAction()
dispatchAction={({ draftAction }) =>
new Promise(resolve => {
this.setState({ isDraftAction: draftAction }, resolve);
})
}