To implement a custom wizard form, you can use the common wizard component. This component provides basic functionality such as branching, submitting only visited values, etc. Also, this wizard is used in all of our provided mappers.
When implementing custom wizard, please keep it under wizard
component key so the schema validator won't expect that nested fields (=wizard steps definitions) have a component property. If this is not possible, you can implement a mock component that will be used as a component for wizard steps.
To use the component import it from the common package:
import Wizard from '@data-driven-forms/common/wizard';
And use your wizard component as Wizard
prop:
const CustomWizard = (props) => { ... }const WrappedWizard = (props) => <Wizard Wizard={CustomWizard} {...props} />
Custom wizard (and all other nested components) then can access the wizard api via WizardContext
:
import WizardContext from '@data-driven-forms/react-form-renderer/wizard-context';const CustomWizard = (props) => {const {crossroads,formOptions,currentStep,handlePrev,onKeyDown,jumpToStep,setPrevSteps,handleNext,navSchema,activeStepIndex,maxStepIndex,isDynamic} = useContext(WizardContext);...}
You can notice that this context also contains formOptions
. It contains the same functions as the regular one, however, some of the functions are enhanced to support wizard functionality.
Props | Type | Required | Default | Description |
---|---|---|---|---|
name | string,number | no | undefined | Name of the step |
nextStep | object/stepKey of next step/function | no | undefined | See below |
fields | array | yes | undefined | As usual |
conditionalSubmitFlag | string | no | "@@ddf-common-wizard__conditional-submit-step" | See below |
A) string - no branching, name of the next step
{nextStep: 'next-step-name'}
B) object - simple branching
nextStep: {when: 'source-type',stepMapper: {aws: 'aws-step',google: 'google-step',...},},
i.e.: When source-type
is asw
go to to the aws-step
.
C) function - complex branching
another option is to use custom function. The custom function receives as the first argument an object with values and the function has to return a name
in string.
nextStep: ({ values }) => (values.aws === '123' &&& values.password === 'secret') ? 'secretStep' : 'genericStep'
D) conditional submit step
Based on a form state value, a step can change into the last step in the wizard and show submit button instead of next button.
With default constant: @@ddf-common-wizard__conditional-submit-step
You can import this constant:
import { CONDITIONAL_SUBMIT_FLAG } from '@data-driven-forms/common/wizard';...// next step definitionnextStep: {when: 'source-type',stepMapper: {aws: 'aws-step',google: CONDITIONAL_SUBMIT_FLAG,...},},
Or with custom constant value defined by conditionalSubmitFlag
prop:
const schema = {fields: [{{"component": "wizard","name": "wizard",// custom flag definitionconditionalSubmitFlag: 'make-me-final-step',fields: [{name: 'step-1',// next step definitionnextStep: {when: 'value',stepMapper: {"value-one": 'step-2',"value-two": 'make-me-final-step',},}...}, {name: 'step-2'...}]...}}]}
It is possible to set the initial state of the wizard component. This can be useful when an application returns users to a specific step.
{component: 'wizard',..., // fields, etc.initialState: {activeStep: 'second-step', // name of the active stepactiveStepIndex: 1, // active indexmaxStepIndex: 1, // max achieved indexprevSteps: ['first-step'], // array with names of previously visited stepsregisteredFieldsHistory: { 'first-step': ['field'] }// array of registered fields for each visited step// only values from registered fields will be submitted}}
How to get the state from existing wizard? The state is passed to both onCancel
and onSubmit
:
A) onSubmit
- (values, formApi, wizardState) => ...
B) onCancel
- (values, wizardState) => ...
Wizard share its configuration and props via WizardContext
.
import WizardContext from '@data-driven-forms/react-form-renderer/wizard-context';const {crossroads, // variables changing the navigationformOptions, // modified formOptions with submit and cancel handlerscurrentStep, // curent step objecthandlePrev, // going back in the wizardonKeyDown, // overrides form onKeyDown event for the wizardjumpToStep, // jump to step, jumpToStep(index, formOptions.valid)setPrevSteps, // rewrites the nav schema, use to change the navigationhandleNext, // jumps to the nextStep: handleNext(nextStep)navSchema, // internal object representing the schema of current wizard flowactiveStepIndex, // active index of the stepmaxStepIndex, // maximal achieved stepisDynamic, // if form is dynamic (= it is branching steps)prevSteps // array with names of previous steps} = useContext(WizardContext);
This API is subject to change. If you implement custom components using these variables and functions, make sure that it is fully tested to prevent bugs when updating.
Following example shows only the basic custom implementation. To see other functionality as a dynamic navigation, check implementation in one of our mappers. (The PF4 wizard provides the most complex functionality.)