diff --git a/src/modules/wizard/components/PagesWithReduxForm.js b/src/modules/wizard/components/PagesWithReduxForm.js new file mode 100644 index 0000000..6445b15 --- /dev/null +++ b/src/modules/wizard/components/PagesWithReduxForm.js @@ -0,0 +1,30 @@ +import React from "react"; +import WithReduxFormWizardPageValidation from "./WithReduxFormWizardPageValidation"; + +const PagesWithReduxForm = ({ + handleSubmit, + currentPageIndex, + pagesCount, + currentPage +}) => { + return ( +
+ {React.createElement(currentPage.component)} +
+ ); +}; + +export default WithReduxFormWizardPageValidation(PagesWithReduxForm, props => { + return { + isLastPage: + props && props.currentPageIndex + 1 === props.pagesCount ? true : false, + formName: "PageWithReduxFormsValidations", + requiresInitialization: false + }; +}); diff --git a/src/modules/wizard/components/WithReduxFormWizardPageValidation.js b/src/modules/wizard/components/WithReduxFormWizardPageValidation.js index a275456..6b0c3d0 100644 --- a/src/modules/wizard/components/WithReduxFormWizardPageValidation.js +++ b/src/modules/wizard/components/WithReduxFormWizardPageValidation.js @@ -1,69 +1,68 @@ import React from "react"; -import ValidatingReduxFormWizardPageContainer from "./ValidatingReduxFormWizardPageContainer"; -import { reduxForm, SubmissionError } from "redux-form"; import _ from "lodash"; +import { reduxForm, SubmissionError } from "redux-form"; +import ValidatingReduxFormWizardPageContainer from "./ValidatingReduxFormWizardPageContainer"; import { getWizardErrors } from "../wizard.selectors"; import { getState } from "../../store"; -const WithReduxFormWizardPageValidation = ( - wrappedComponent, - { - formName, - handlesValidation, - requiresInitialization = false, - isLastPage = false - } -) => { - let config; +const WithReduxFormWizardPageValidation = (wrappedComponent, data) => { + return class extends React.Component { + constructor(props) { + super(props); + let config = {}; + if (data(props).isLastPage) { + config = { + form: data(props).formName, + destroyOnUnmount: false, + forceUnregisterOnUnmount: true, + keepDirtyOnReinitialize: true, + enableReinitialize: true + }; + } else { + config = { + form: data(props).formName, + destroyOnUnmount: false, + forceUnregisterOnUnmount: true, + onSubmit: submit + }; + } + this.state = { + config + }; + } - if (isLastPage) { - config = { - form: formName, - destroyOnUnmount: false, - forceUnregisterOnUnmount: true, - keepDirtyOnReinitialize: true, - enableReinitialize: true - }; - } else { - config = { - form: formName, - destroyOnUnmount: false, - forceUnregisterOnUnmount: true, - onSubmit: submit - }; - } + render() { + const page = reduxForm(this.state.config)(wrappedComponent); + return ( + + {React.createElement(page, this.props)} + + ); + } + }; - const page = reduxForm(config)(wrappedComponent); + // values left so we know it's available + function submit() { + // We can do form level validations here if needed using values + const wizardErrors = getWizardErrors(getState()); - return props => ( - - {React.createElement(page, props)} - - ); -}; - -// values left so we know it's available -function submit() { - // We can do form level validations here if needed using values - - const wizardErrors = getWizardErrors(getState()); + if (!_.isEmpty(wizardErrors)) { + // We've got errors so let redux form know by returning a rejected promise + return Promise.reject( + new SubmissionError({ + ...wizardErrors + }) + ); + } - if (!_.isEmpty(wizardErrors)) { - // We've got errors so let redux form know by returning a rejected promise - return Promise.reject( - new SubmissionError({ - ...wizardErrors - }) - ); + // No errors so let redux form know we are all good by returning a resolved promise + return Promise.resolve(); } - - // No errors so let redux form know we are all good by returning a resolved promise - return Promise.resolve(); -} +}; export default WithReduxFormWizardPageValidation; diff --git a/src/modules/wizard/components/Wizard.js b/src/modules/wizard/components/Wizard.js index 02bb516..8c2648f 100644 --- a/src/modules/wizard/components/Wizard.js +++ b/src/modules/wizard/components/Wizard.js @@ -1,6 +1,7 @@ import React, { Fragment } from "react"; import classNames from "classnames"; import "./wizard.css"; +import PagesWithReduxForm from "./PagesWithReduxForm"; const Step = ({ stepNumber, currentStep, page }) => { const isCurrentStep = stepNumber === currentStep; @@ -78,9 +79,20 @@ const Wizard = ({

{pages && pages[currentPage] && pages[currentPage].title}

{currentPage >= 0 && + pages[currentPage].hasOwnProperty("props") && + pages[currentPage].props.hasOwnProperty("formName") ? ( + + ) : ( + currentPage >= 0 && React.createElement(pages[currentPage].component, { ...pages[currentPage].props - })} + }) + )} +
diff --git a/src/modules/wizard/components/WizardContainer.js b/src/modules/wizard/components/WizardContainer.js index 9ac10d0..369a4fa 100644 --- a/src/modules/wizard/components/WizardContainer.js +++ b/src/modules/wizard/components/WizardContainer.js @@ -15,7 +15,6 @@ import { wizardStates } from "../wizard.constants"; export class WizardContainer extends Component { componentDidMount() { const { pages, startWizard, name } = this.props; - startWizard(name, pages.length); } @@ -36,6 +35,17 @@ export class WizardContainer extends Component { nextClicked } = this.props; + let pagesWithReduxForm = []; + if (pages) { + pagesWithReduxForm = pages.reduce((acc, field, index) => { + if (field.props && field.props.formName) { + field.index = index; + acc.push(field); + } + return acc; + }, []); + } + return ( ); } diff --git a/src/screens/wizardExample/components/WizardExampleContainer.js b/src/screens/wizardExample/components/WizardExampleContainer.js index 84db117..12ae32e 100644 --- a/src/screens/wizardExample/components/WizardExampleContainer.js +++ b/src/screens/wizardExample/components/WizardExampleContainer.js @@ -1,5 +1,6 @@ import React, { Component } from "react"; import { connect } from "react-redux"; +import { SubmissionError } from "redux-form"; import wizard from "../../../modules/wizard"; import PageWithValidations from "./samplePages/PageWithValidations"; import PageWithInitializations from "./samplePages/PageWithInitializations"; @@ -30,6 +31,26 @@ class WizardExampleContainer extends Component { } } + handleSubmit = values => { + if ( + values.requiredText && + values.requiredText.toLowerCase() === "servererror" + ) { + const errors = { + requiredText: "A fake server error occurred. Please try again." + }; + + const addEditPromoDetailsPage = 4; + this.props.pageNotValid(addEditPromoDetailsPage); + + throw new SubmissionError(errors); + } + + alert(`Submit succeeded with values: ${JSON.stringify(values)}`); + + return Promise.resolve("Success!"); + }; + render() { return (
@@ -58,10 +79,14 @@ class WizardExampleContainer extends Component { title: "Step 5: Page with redux forms validations", props: { formName: "PageWithReduxFormsValidations" } }, + { component: LastPageOfWizardWithReduxFormsValidations, title: "Step 6: Last page with redux forms validations", - props: { formName: "PageWithReduxFormsValidations" } + props: { + formName: "PageWithReduxFormsValidations", + onSubmit: this.handleSubmit + } } ]} formName="PageWithReduxFormsValidations" @@ -75,4 +100,7 @@ const mapStateToProps = state => ({ wizard: getWizardState(state) }); -export default connect(mapStateToProps)(WizardExampleContainer); +export default connect( + mapStateToProps, + { pageNotValid: wizard.actions.pageNotValid } +)(WizardExampleContainer); diff --git a/src/screens/wizardExample/components/samplePages/LastPageOfWizardWithReduxFormsValidations.js b/src/screens/wizardExample/components/samplePages/LastPageOfWizardWithReduxFormsValidations.js index 16b1301..ea2731f 100644 --- a/src/screens/wizardExample/components/samplePages/LastPageOfWizardWithReduxFormsValidations.js +++ b/src/screens/wizardExample/components/samplePages/LastPageOfWizardWithReduxFormsValidations.js @@ -1,5 +1,5 @@ import React from "react"; -import { Field, SubmissionError } from "redux-form"; +import { Field } from "redux-form"; import { connect } from "react-redux"; import "../wizardExample.css"; import wizard from "../../../../modules/wizard"; @@ -10,53 +10,19 @@ const { validators: { required } } = forms; -const { - components: { WithReduxFormWizardPageValidation } -} = wizard; - -let PageWithReduxFormsValidations = ({ onSubmit, handleSubmit, ...rest }) => ( -
- - -); - -PageWithReduxFormsValidations = WithReduxFormWizardPageValidation( - PageWithReduxFormsValidations, - { - formName: "PageWithReduxFormsValidations", - isLastPage: true - } +const PageWithReduxFormsValidations = () => ( + ); class PageWithReduxFormsValidationsContainer extends React.Component { - handleSubmit = values => { - if ( - values.requiredText && - values.requiredText.toLowerCase() === "servererror" - ) { - const errors = { - requiredText: "A fake server error occurred. Please try again." - }; - - const addEditPromoDetailsPage = 4; - this.props.pageNotValid(addEditPromoDetailsPage); - - throw new SubmissionError(errors); - } - - alert(`Submit succeeded with values: ${JSON.stringify(values)}`); - - return Promise.resolve("Success!"); - }; - render() { - return ; + return ; } } diff --git a/src/screens/wizardExample/components/samplePages/PageWithReduxFormsValidations.js b/src/screens/wizardExample/components/samplePages/PageWithReduxFormsValidations.js index 0eab7cb..74b7b4b 100644 --- a/src/screens/wizardExample/components/samplePages/PageWithReduxFormsValidations.js +++ b/src/screens/wizardExample/components/samplePages/PageWithReduxFormsValidations.js @@ -1,7 +1,6 @@ import React from "react"; import { Field } from "redux-form"; import "../wizardExample.css"; -import wizard from "../../../../modules/wizard"; import forms from "../../../../modules/forms"; const { @@ -9,23 +8,14 @@ const { validators: { required } } = forms; -const { - components: { WithReduxFormWizardPageValidation } -} = wizard; - -const PageWithReduxFormsValidations = props => ( -
- - +const PageWithReduxFormsValidations = () => ( + ); -export default WithReduxFormWizardPageValidation( - PageWithReduxFormsValidations, - { formName: "PageWithReduxFormsValidations" } -); +export default PageWithReduxFormsValidations;