Skip to content

Commit 563d657

Browse files
Added example wizard pages for pages with validation and for pages that require intialization
1 parent 049b2a8 commit 563d657

File tree

9 files changed

+214
-40
lines changed

9 files changed

+214
-40
lines changed

src/modules/wizard/components/ValidatingReduxFormWizardPageContainer.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,14 @@ export class ValidatingReduxFormWizardPageContainer extends React.Component {
2121
this.tryToValidateForm = this.tryToValidateForm.bind(this);
2222
this.tryDestroyForm = this.tryDestroyForm.bind(this);
2323
this.startReduxFormsValidation = this.startReduxFormsValidation.bind(this);
24-
this.handleWizardStateMachineTransitions = this.handleWizardStateMachineTransitions.bind(
25-
this
26-
);
24+
this.transitionStateMachine = this.transitionStateMachine.bind(this);
2725

2826
this.state = { validate: false };
2927
}
3028

3129
componentWillReceiveProps(nextProps) {
3230
if (nextProps.wizard.currentState !== this.props.wizard.currentState) {
33-
this.handleWizardStateMachineTransitions(nextProps);
31+
this.transitionStateMachine(nextProps);
3432
return;
3533
}
3634

@@ -68,7 +66,7 @@ export class ValidatingReduxFormWizardPageContainer extends React.Component {
6866
}
6967
}
7068

71-
handleWizardStateMachineTransitions(nextProps) {
69+
transitionStateMachine(nextProps) {
7270
switch (nextProps.wizard.currentState) {
7371
case wizardStates.PAGE_INITIALIZED: {
7472
this.props.pageRequiresValidation();
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import React, { Fragment } from "react";
2+
import { connect } from "react-redux";
3+
import WizardPage from "./WizardPageContainer";
4+
import * as wizardActions from "../wizard.actions";
5+
import { getWizardState, wizardStateChanged } from "../wizard.selectors";
6+
import { wizardStates } from "../wizard.constants";
7+
8+
class ValidatingWizardPage extends React.Component {
9+
componentDidUpdate(prevProps) {
10+
if (wizardStateChanged(prevProps, this.props)) {
11+
this.transitionStateMachine(this.props);
12+
}
13+
}
14+
15+
transitionStateMachine({ wizard, validating } = {}) {
16+
switch (wizard.currentState) {
17+
case wizardStates.DONE_REQUESTED:
18+
case wizardStates.VALIDATION_REQUESTED: {
19+
validating();
20+
break;
21+
}
22+
default: {
23+
break;
24+
}
25+
}
26+
}
27+
28+
render() {
29+
return (
30+
<Fragment>
31+
<WizardPage requiresValidation>{this.props.children}</WizardPage>
32+
</Fragment>
33+
);
34+
}
35+
}
36+
37+
const mapStateToProps = state => {
38+
return {
39+
wizard: getWizardState(state)
40+
};
41+
};
42+
43+
const mapDispatchToProps = {
44+
validating: wizardActions.validating
45+
};
46+
47+
export default connect(
48+
mapStateToProps,
49+
mapDispatchToProps
50+
)(ValidatingWizardPage);

src/modules/wizard/components/WizardContainer.js

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React, { Component } from "react";
22
import { connect } from "react-redux";
33
import Wizard from "./Wizard";
44
import "./wizard.css";
5-
import * as selectors from "../wizard.selectors";
5+
import { getWizardState, wizardStateChangedTo } from "../wizard.selectors";
66
import {
77
resetWizard,
88
doneClicked,
@@ -20,11 +20,8 @@ export class WizardContainer extends Component {
2020
startWizard(name, pages.length);
2121
}
2222

23-
componentWillReceiveProps(nextProps) {
24-
if (
25-
nextProps.currentState === wizardStates.DONE &&
26-
nextProps.currentState !== this.props.currentState
27-
) {
23+
componentDidUpdate(prevProps) {
24+
if (wizardStateChangedTo(prevProps, this.props, wizardStates.DONE)) {
2825
this.props.resetWizard();
2926
}
3027
}
@@ -64,7 +61,7 @@ const mapDispatchToProps = {
6461
};
6562

6663
const mapStateToProps = state => {
67-
const wizardState = selectors.getWizardState(state);
64+
const wizardState = getWizardState(state);
6865
return {
6966
...wizardState,
7067
isLastPage: wizardState.currentPage === wizardState.numberOfPages - 1 // TODO: Ryan - this should come back as part of wizard state

src/modules/wizard/components/WizardPageContainer.js

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
11
import React, { Fragment } from "react";
22
import { connect } from "react-redux";
3-
import {
4-
pageRequiresValidation,
5-
finishedDisposing,
6-
initialized,
7-
canTransition
8-
} from "../wizard.actions";
9-
import { getWizardState } from "../wizard.selectors";
3+
import * as wizardActions from "../wizard.actions";
4+
import { getWizardState, wizardStateChanged } from "../wizard.selectors";
105
import { wizardStates } from "../wizard.constants";
116

127
class WizardPageContainer extends React.Component {
@@ -15,7 +10,7 @@ class WizardPageContainer extends React.Component {
1510
}
1611

1712
componentDidUpdate(prevProps) {
18-
if (this.props.wizard.currentState !== prevProps.wizard.currentState) {
13+
if (wizardStateChanged(prevProps, this.props)) {
1914
this.transitionStateMachine(this.props);
2015
}
2116
}
@@ -25,6 +20,7 @@ class WizardPageContainer extends React.Component {
2520
requiresInitialization,
2621
initialized,
2722
requiresValidation,
23+
pageRequiresValidation,
2824
canTransition,
2925
finishedDisposing
3026
} = {}) {
@@ -37,7 +33,7 @@ class WizardPageContainer extends React.Component {
3733
}
3834
case wizardStates.PAGE_INITIALIZED: {
3935
if (requiresValidation) {
40-
requiresValidation();
36+
pageRequiresValidation();
4137
} else {
4238
canTransition();
4339
}
@@ -65,10 +61,10 @@ const mapStateToProps = state => {
6561
};
6662

6763
const mapDispatchToProps = {
68-
pageRequiresValidation,
69-
finishedDisposing,
70-
initialized,
71-
canTransition
64+
pageRequiresValidation: wizardActions.pageRequiresValidation,
65+
finishedDisposing: wizardActions.finishedDisposing,
66+
initialized: wizardActions.initialized,
67+
canTransition: wizardActions.canTransition
7268
};
7369

7470
export default connect(

src/modules/wizard/components/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import Wizard from "./WizardContainer";
2+
import ValidatingWizardPage from "./ValidatingWizardPageContainer";
23
import ValidatingReduxFormWizardPage from "./ValidatingReduxFormWizardPageContainer";
34
import WithReduxFormWizardPageValidation from "./WithReduxFormWizardPageValidation";
45
import WizardPage from "./WizardPageContainer";
56

67
export default {
78
Wizard,
9+
ValidatingWizardPage,
810
ValidatingReduxFormWizardPage,
911
WithReduxFormWizardPageValidation,
1012
WizardPage
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,25 @@
11
import * as constants from "./wizard.constants";
22

3+
const { wizardStates } = constants;
4+
5+
export const wizardStateChangedTo = (prevProps, props, targetState) =>
6+
(!prevProps.wizard || prevProps.wizard.currentState !== targetState) &&
7+
(props.wizard && props.wizard.currentState === targetState);
8+
39
export const getWizardState = state => state[constants.STATE_NAME].stateData;
410
export const getWizardData = state => state[constants.STATE_NAME].data;
511
export const getWizardErrors = state => getWizardData(state).errors || {};
612
export const getForm = (state, formName) => state.form[formName];
13+
14+
export const wizardIsDisposing = (prevProps, props) =>
15+
wizardStateChangedTo(prevProps, props, wizardStates.DISPOSING);
16+
17+
export const wizardIsDone = (prevProps, props) =>
18+
wizardStateChangedTo(prevProps, props, wizardStates.DONE);
19+
20+
export const wizardStateChanged = (prevProps, props) =>
21+
props.wizard.currentState !== prevProps.wizard.currentState;
22+
23+
export const validationRequested = (prevProps, props) =>
24+
wizardStateChangedTo(prevProps, props, wizardStates.VALIDATING) ||
25+
wizardStateChangedTo(prevProps, props, wizardStates.VALIDATING_DONE);
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import React, { Component } from "react";
2+
import { connect } from "react-redux";
3+
import wizard from "../../../modules/wizard";
4+
import { wizardStates } from "../../../modules/wizard/wizard.constants";
5+
6+
const {
7+
components: { WizardPage },
8+
selectors: { getWizardState }
9+
} = wizard;
10+
11+
class PageWithValidationLogic extends Component {
12+
state = {
13+
isInitialized: false
14+
};
15+
16+
componentDidMount() {
17+
setTimeout(() => this.setState({ isInitialized: true }), 500);
18+
}
19+
20+
componentDidUpdate(_, prevState) {
21+
if (this.props.wizard.currentState === wizardStates.INITIALIZING) {
22+
alert("Here we can check to see if we are don initializing");
23+
24+
if (!prevState.isInitialized && this.state.isInitialized) {
25+
alert("We are initialized");
26+
// We call the initialized action to let the wizard know we are initialized
27+
this.props.initialized();
28+
} else {
29+
alert("We aren't initialized yet");
30+
}
31+
}
32+
}
33+
34+
render() {
35+
return (
36+
<WizardPage requiresInitialization>
37+
<h1>Page with Initializations</h1>
38+
</WizardPage>
39+
);
40+
}
41+
}
42+
43+
const mapStateToProps = state => ({
44+
wizard: getWizardState(state)
45+
});
46+
47+
const mapDispatchToProps = {
48+
initialized: wizard.actions.initialized
49+
};
50+
51+
export default connect(
52+
mapStateToProps,
53+
mapDispatchToProps
54+
)(PageWithValidationLogic);
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import React, { Component } from "react";
2+
import { connect } from "react-redux";
3+
import wizard from "../../../modules/wizard";
4+
5+
const {
6+
components: { ValidatingWizardPage },
7+
selectors: { validationRequested, getWizardState }
8+
} = wizard;
9+
10+
class PageWithValidationLogic extends Component {
11+
state = {
12+
isValid: false
13+
};
14+
15+
componentDidUpdate(prevProps) {
16+
if (validationRequested(prevProps, this.props)) {
17+
alert("Here we would do validations");
18+
19+
if (this.state.isValid) {
20+
alert("We are valid");
21+
// We call the pageValid action to let the wizard know we are valid
22+
this.props.pageValid();
23+
} else {
24+
alert("We aren't valid");
25+
// We call the pageNotValid action to let the wizard know we aren't valid
26+
this.props.pageNotValid();
27+
}
28+
}
29+
}
30+
31+
render() {
32+
return (
33+
<ValidatingWizardPage>
34+
<h1>Page 2</h1>
35+
<button onClick={() => this.setState({ isValid: true })}>
36+
we are valid
37+
</button>
38+
</ValidatingWizardPage>
39+
);
40+
}
41+
}
42+
43+
const mapStateToProps = state => ({
44+
wizard: getWizardState(state)
45+
});
46+
47+
const mapDispatchToProps = {
48+
pageValid: wizard.actions.pageValid,
49+
pageNotValid: wizard.actions.pageNotValid
50+
};
51+
52+
export default connect(
53+
mapStateToProps,
54+
mapDispatchToProps
55+
)(PageWithValidationLogic);

src/screens/wizardExample/components/WizardExampleContainer.js

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,34 @@ import React, { Component } from "react";
22
import { connect } from "react-redux";
33
// import { reduxForm, Field } from "redux-form";
44
import wizard from "../../../modules/wizard";
5+
import PageWithValidations from "./PageWithValidations";
6+
import PageWithInitializations from "./PageWithInitializations";
57

68
const {
79
components: { Wizard, WizardPage },
8-
constants: { wizardStates },
9-
selectors: { getWizardState }
10+
selectors: { getWizardState, wizardIsDisposing, wizardIsDone }
1011
} = wizard;
1112

12-
const PageOne = ({ passedInData }) => (
13+
const PageWithProps = ({ passedInData }) => (
1314
<WizardPage>
1415
<h1>Page 1 {passedInData}</h1>
1516
</WizardPage>
1617
);
1718

1819
const PageTwo = () => (
1920
<WizardPage>
20-
<h1>Page 2</h1>
21+
<h1>Page 4</h1>
2122
</WizardPage>
2223
);
2324

2425
class WizardExampleContainer extends Component {
2526
componentDidUpdate(prevProps) {
26-
if (
27-
prevProps.wizard.currentState !== wizardStates.DISPOSING &&
28-
this.props.wizard.currentState === wizardStates.DISPOSING
29-
) {
27+
if (wizardIsDisposing(prevProps, this.props)) {
3028
// This is where you can clean up call back references, release handles, etc...
3129
alert("Wizard is disposing, clean up here...");
3230
}
3331

34-
if (
35-
prevProps.wizard.currentState !== wizardStates.DONE &&
36-
this.props.wizard.currentState === wizardStates.DONE
37-
) {
32+
if (wizardIsDone(prevProps, this.props)) {
3833
// Note that if you are using redux forms you will likely not use
3934
// this block and will instead use redux form's submit handler instead
4035
alert(
@@ -50,13 +45,21 @@ class WizardExampleContainer extends Component {
5045
<Wizard
5146
pages={[
5247
{
53-
component: PageOne,
48+
component: PageWithProps,
5449
props: { passedInData: "Some passed in text" },
55-
title: "Step 1: Page 1 Title"
50+
title: "Step 1: Page with Props"
51+
},
52+
{
53+
component: PageWithValidations,
54+
title: "Step 2: Page Validation Logic"
55+
},
56+
{
57+
component: PageWithInitializations,
58+
title: "Step 3: Page with initializations"
5659
},
5760
{
5861
component: PageTwo,
59-
title: "Step 2: Page 2 Title"
62+
title: "Step 4: Page with initializations"
6063
}
6164
]}
6265
/>

0 commit comments

Comments
 (0)