I am using Redux forms with multiple submit buttons along with redux-form <Field />
. I need to control the validation of these fields based on click of these buttons. For ex. I need to set a flag to True/False based on click of these buttons so that I can conditionally validate my fields like below:
<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"
/>
As you can see from above code, I'm conditionally validating my fields with validate={isSaveDraft && [validateRequiredText]} and validate={!isSaveDraft && [validateRequiredText]}
Here are my two submit buttons:
<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
/>
However, I'm not able to achieve it. Please help.
After a lot of headaches and head scratching, I've finally found the solution without making things look ugly. Thanks to a fellow developer for this solution. Original idea was to set a flag on click of the button and conditionally validate the fields. (PS: I'm using Field Level Validations). However, the issue was that the validations are being executed BEFORE the flag setting as the onClick handler wouldn't fire before all the validations are fixed and that logic is buried deep inside redux-forms (perks of unnecessarily overcomplicating simple things by using a library).
Here is the solution:
submit handler
handleSubmit() {
const { bookingCreate, modalShow, navigateTo } = this.props;
const { isDraftAction } = this.state; // my flag
// create record!
return bookingCreate(isDraftAction)
.then(responsePayload => {
...
})
.catch(handleSubmissionError);
}
isDraftAction
is the flag which is set (in local state)
when the action is called on onClick
of both buttons.
My conditional Field level validations
<Field
name="date"
component={DateFormField}
validate={isDraftAction && [validateRequiredText]}
fullWidth
helpText="blablabla"
/>
<Field
name="title"
component={TextFormField}
normalizeOnBlur={normalizeTextOnBlur}
validate={!isDraftAction && [validateRequiredText]}
fullWidth
helpText="blablabla"
/>
My 2 buttons for SAVE RECORD and 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()
is my action function which will FIRST set the flag to true/false THEN call redux-forms inbuilt submit handler. Also, I've extracted the redux-form's submit handler as it is above only for more clarity.
dispatchAction()
dispatchAction={({ draftAction }) =>
new Promise(resolve => {
this.setState({ isDraftAction: draftAction }, resolve);
})
}