Skip to main content
Version: 13.x (Current)

Form Wizard

<bk-form-wizard></bk-form-wizard>

wizard-form-modal

The Form Wizard is an extension of the Dynamic Form Modal that allows to split data insertion / editing into multiple steps. Each step consists of a form or an accordion of forms and allows to fill-in / edit a subset of the data properties. Navigation through wizard steps is possible through buttons displayed inside the footer of the modal. Upon reaching the last step, it is possible to submit the wizard, which signals the need for an item creation / update, with data obtained by aggregating form values from each of the wizard steps.

How to configure

For basic usage of the Form Wizard Providing a data-schema to interpret the structure of the data to handle is sufficient. Several customizations can be applied to the provided data-schema that tune how the data is handled by the component. Particularly, but not limited to, every field supports a set of options specific for forms.

Additionally, by default, the From Wizard analyzes the provided data-schema to automatically configure each step of the wizard. All fields that are not nested objects or nested arrays are displayed as a form in the first step of the modal. Each of the following steps is composed of a single nested object or array field, the fields of which are editable through a form.

{
"tag": "bk-form-wizard",
"properties": {
"dataSchema": {
"type": "object",
"properties": {
"_id": {
"type": "string"
},
"__STATE__": {
"type": "string"
},
"name": {
"type": "string"
},
"price": {
"type": "number"
},
"color": {
"type": "object",
"dataSchema": {
"type": "object",
"properties": {
"red": {"type": "number"},
"green": {"type": "number"},
"blue": {"type": "number"}
}
}
},
"variants": {
"type": "array",
"items": {
"type": "object",
"properties": {
"shape": {"type": "string"},
"size": {"type": "string"}
}
}
}
}
}
}
}

A Form Wizard configured as above results in a wizard with three steps.

  • the first step displays a form with fields "_id", "__STATE__", "name", "price"
  • the second step displays a form with fields "red", "green", "blue"
  • the third step displays an accordion of forms, each one with fields "shape", "size"

wizard-form-modal-accordion

The Form Wizard can be opened in two different modes, just like the Dynamic Form Modal:

  • insert: submitting the form signals the need for an item creation. This mode is activated upon listening to an add-new event
  • edit: submitting the form signals the need for an item creation. This mode is activated upon listening to an selected-data event

Customize wizard steps

Property wizard allows to configure each step specifying an array of objects with three properties, keys, labels, asForm.

type WizardStepSchema = {
keys: string[],
labels: {
wizardNext?: LocalizedText
wizardPrevious?: LocalizedText
wizardAddNew?: LocalizedText
stepperTitle?: LocalizedText
stepperSubtitle?: LocalizedText
accordionHeader?: LocalizedText
accordionEmptyComponent?: LocalizedText
}
asForm?: boolean
}

Each such element maps to a step of the wizard as follows:

propertydescription
keysfields to display in the step
labelslocalized labels with the text to show
asFormwhether to visualize nested objects as a form, or nested arrays as an accordion of forms. Step must include one field. Defaults to true.

If a step meets the following requirements:

  • only includes one field
  • the field is of type object or array and has a property dataSchema
  • asForm is set to true (as per default)

Then the field will be displayed as a form in case of an object field, or as an accordion of forms in case of an array field.

labels are mapped to displayed text as follows:

keydescription
wizardNextButton for going to next step
wizardPreviousButton for going back to previous step
wizardAddNewButton for adding a new element to an array, when displayed as an accordion
wizardSubmitButton for submitting the form in the final step
stepperTitleTitle of the stepper component
stepperSubtitleSubtitle of the stepper component
accordionHeaderTitle of the accordion panel. An incremental is automatically added as panels are added to the accordion
accordionEmptyComponentText to display when the accordion is empty

Dynamic Context

Analogously to the Dynamic Form Modal, several properties of the Wizard Form allow dynamic configurations. By default, such properties are parsed with handlebars, injecting the current state of the whole wizard as context through key values, and the state of the current step through key step, as well as other information.

{
values: Record<string, any> // aggregated values of all steps
step: Record<string, any> // values of current step
currentUser: Record<string, any> // information on currently logged user, if available
}

After Submission

The Form Wizard supports properties onSuccess and onFail, that allow to append extra tasks to be executed after the successful or unsuccessful submission of the wizard, just like the Dynamic Form Modal.

Extra context key step is available in context injected into onSuccess and onFail actions:

{
currentUser: Record<string, any>
values: Record<string, any>
step: Record<string, any>
response: Record<string, any>
}

where step is the state of the form of the current step, values is the aggregated values of all steps, response contains an object representation of the content of the payload of the success event linked to the submission request.

By deafult, the footer of the modal rendered by Form Wizard includes the following buttons:

  • two buttons for navigating through the wizard steps,
  • a button to add a new form to an accordion of forms, in case the current step includes a single field of type array of objects,
  • in case the current step is the last step of the wizard, a submit button. This can be used for signaling the need to add or edit an item in CRUD collection, depending on the operating mode.

Extra buttons

Other than the default buttons included in the modal footer, extra buttons can be specified to be included in the modal footer, using property actions, just like the Dynamic Form Modal.

Extra buttons are added to the footer of the modal for each step of the wizard.

Omitting submit button

It is possible to omit the default submission button by setting property omitSubmit to true.

Confirmation dialog on save and on close

It is possible to ask for confirmation on close and/or on save, and also customize the confirmation dialog texts. This is achieved with property requireConfirm, analogously to the Dynamic Form Modal.

Integrate custom labels

Just like the Dynamic Form Modal, custom labels can be specified as localized text, controlling copies within the Form Wizard. Additionally, extra custom labels can be specified for each wizard step.

Working with Views

Analogously to the Dynamic Form Modal, the Wizard Form is designed to be able to interact with Mia-Platform CRUD Service views.

Conditional Fields

Properties conditionalOptions and conditionalValues can be used to set-up custom form behavior that is conditional to the current state of the wizard, just like for the Dynamic Form Modal.

Locale

The texts of the Form Wizard can be customized through the property customLocale, which accepts an object shaped like the following:

type Locale = {
create: {
title: LocalizedText
ctaLabel: LocalizedText
unsavedChangesContent: LocalizedText
saveChangesContent: LocalizedText
wizardNext?: LocalizedText
wizardPrevious?: LocalizedText
wizardAddNew?: LocalizedText
stepperTitle?: LocalizedText
stepperSubtitle?: LocalizedText
accordionHeader?: LocalizedText
accordionEmptyLabel?: LocalizedText
}
update: {
title: LocalizedText
ctaLabel: LocalizedText
unsavedChangesContent: LocalizedText
saveChangesContent: LocalizedText
wizardNext?: LocalizedText
wizardPrevious?: LocalizedText
wizardAddNew?: LocalizedText
stepperTitle?: LocalizedText
stepperSubtitle?: LocalizedText
accordionHeader?: LocalizedText
accordionEmptyLabel?: LocalizedText
},
form: {
validationMessages:{
default: LocalizedText,
required: LocalizedText,
enum: LocalizedText,
whitespace: LocalizedText,
date:{
format: LocalizedText,
parse: LocalizedText,
invalid: LocalizedText
},
types:{
string: LocalizedText,
method: LocalizedText,
array: LocalizedText,
object: LocalizedText,
number: LocalizedText,
date: LocalizedText,
boolean: LocalizedText,
integer: LocalizedText,
float: LocalizedText,
regexp: LocalizedText,
email: LocalizedText,
url: LocalizedText,
hex: LocalizedText,
file: LocalizedText
},
string:{
len: LocalizedText,
min: LocalizedText,
max: LocalizedText,
range: LocalizedText
},
number:{
len: LocalizedText,
min: LocalizedText,
max: LocalizedText,
range: LocalizedText
},
array:{
len: LocalizedText,
min: LocalizedText,
max: LocalizedText,
range: LocalizedText,
unique: LocalizedText
},
pattern:{
mismatch: LocalizedText
}
},
datePicker: {
lang: {
locale: LocalizedText,
placeholder: LocalizedText,
rangePlaceholder: {
start: LocalizedText,
stop: LocalizedText
},
today: LocalizedText,
now: LocalizedText,
backToToday: LocalizedText,
ok: LocalizedText,
clear: LocalizedText,
month: LocalizedText,
year: LocalizedText,
timeSelect: LocalizedText,
dateSelect: LocalizedText,
monthSelect: LocalizedText,
yearSelect: LocalizedText,
decadeSelect: LocalizedText,
monthBeforeYear: 'true' | 'false',
previousMonth: LocalizedText,
nextMonth: LocalizedText,
previousYear: LocalizedText,
nextYear: LocalizedText,
previousDecade: LocalizedText,
nextDecade: LocalizedText,
previousCentury: LocalizedText,
nextCentury: LocalizedText
},
timePickerLocale:{
placeholder: LocalizedText
}
},
filePicker:{
drawerTitle: LocalizedText,
filePickerTitle: LocalizedText,
dragAndDropCaption: LocalizedText,
ctaLabel: LocalizedText
},
objectEditor:{
editorView: LocalizedText,
tableView: LocalizedText
},
editor:{
editorView: LocalizedText,
rawView: LocalizedText
},
htmlEditor: {
preview: LocalizedText,
html: LocalizedText
},
geopoint:{
latitude: LocalizedText,
longitude: LocalizedText,
phLatitude: LocalizedText,
phLongitude: LocalizedText
},
element: LocalizedText,
elements: LocalizedText,
true: LocalizedText,
false: LocalizedText
}
}

where LocalizedText is either a string or an object mapping language acronyms to strings.

Examples

Configuration examples for the Dynamic Form Modal also apply to the Form Wizard.

Example: Default Wizard Steps

A Form Wizard configured like the following:

{
"tag": "bk-form-wizard",
"properties": {
"dataSchema": {
"type": "object",
"properties": {
"_id": {
"type": "string"
},
"__STATE__": {
"type": "string"
},
"name": {
"type": "string"
},
"price": {
"type": "number"
},
"color": {
"type": "object",
"dataSchema": {
"type": "object",
"properties": {
"red": {"type": "number"},
"green": {"type": "number"},
"blue": {"type": "number"}
}
}
},
"variants": {
"type": "array",
"items": {
"type": "object",
"properties": {
"shape": {"type": "string"},
"size": {"type": "string"}
}
}
}
}
}
}
}

results in a wizard with three steps.

  • the first step displays a form with fields "_id", "__STATE__", "name", "price"
  • the second step displays a form with fields "red", "green", "blue"
  • the third step displays an accordion of forms, each one with fields "shape", "size"

Example: Customize Wizard Steps

A Form Wizard configured like the following:

{
"tag": "bk-form-wizard",
"properties": {
"wizard": [
{
"keys": [
"name",
"color"
],
"labels": {
"stepperTitle": {
"en": "Name & Color",
"it": "Nome & Colore"
}
}
},
{
"keys": [
"variants"
],
"labels": {
"stepperSubtitle": {
"en": "Final step",
"it": "Ultimo step"
},
"wizardAddNew": {
"en": "Add new variant",
"it": "Aggiungi nuova variante"
},
"accordionHeader": {
"en": "Variant",
"it": "Variante"
}
}
}
],
"dataSchema": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"color": {
"type": "object",
"dataSchema": {
"type": "object",
"properties": {
"red": {"type": "number"},
"green": {"type": "number"},
"blue": {"type": "number"}
}
}
},
"variants": {
"type": "array",
"items": {
"type": "object",
"properties": {
"shape": {"type": "string"},
"size": {"type": "string"}
}
}
}
}
}
}
}

results in a wizard with two steps:

  • the first step displays a form with fields "name", "color". Note that "color" is not displayed as a separate form, but rather as a default object field - which consists of a text editor
  • the second step displays an accordion of forms, each one with fields "shape", "size"

Note that custom labels are specified for both steps.

API

Properties & Attributes

PropertyAttributeTypeDefaultDescription
rootElementSelectorroot-element-selectorstring-Selector to specify where the container should be appended
dataSchema-ExtendedJSONSchema7Definition-Data schema describing the fields of the collection to filter
wizard-WizardStepSchema-Array of options for setting up the wizard steps. A default wizard is utilized is not specified
width-string | number-Width of the modal
height-string | number-Height of the modal
omitSubmitomit-submitbooleanfalseWhether or not to include the default submit button
actions-ButtonWithClose[] | {insert: ButtonWithClose[]; select: ButtonWithClose[]}-Actions added as buttons to the footer
liveSearchItemsLimitlive-search-items-limitnumber10Max items to fetch on regex live search
customLabels-CustomLabels | {insert: CustomLabels, update: CustomLabels}-Custom localized texts shown as title and CTA button label
requireConfirm-boolean | RequireConfirmOpts | {onSave: RequireConfirmOpts, onSave: RequireConfirmOpts}falseWhether or not the component should request confirmation before closing and/or before saving
onSuccess-Action[] | {insert: Action[], update: Action[]}-Action executed after successful submit
onFail-Action[] | {insert: Action[], update: Action[]}-Action executed after failing submit
lookupQueries-LookupQueries-Extra queries when fetching options for lookup fields in views
conditionalOptions-ConditionalOption[]-Allows specifying dynamic conditions for form-options (hidden / disabled / readonly) to be applied
conditionalValues-Condition[]-Allows specifying dynamic conditions for resetting field
fileFieldsPreviewfile-fields-previewboolean-Enables preview of uploaded files in drag-n-drop file fields
enableSubmitOnFormUntouchedenable-submit-on-form-untouchedboolean-Allows submitting an unedited form
basePath-string-The URL base path to which to send HTTP requests, used when fetching options for lookup field in views

ButtonWithClose

type ButtonWithClose = Partial<BkButton> & {
closeAfter?: boolean
}

where BkButton references the properties of the Button component.

RequireConfirmOpts

type RequireConfirmOpts = boolean | {
cancelText?: LocalizedText
okText?: LocalizedText
content?: LocalizedText
title?: LocalizedText
}

where LocalizedText is either a string or an object mapping language acronyms to strings.

CustomLabels

type CustomLabels = {
title?: LocalizedText
ctaLabel?: LocalizedText
saveChangesContent?: LocalizedText
unsavedChangesContent?: LocalizedText
}

where LocalizedText is either a string or an object mapping language acronyms to strings.

LookupQueries

type LookupQueries = {
[property: string]: Record<string, unknown> | Record<string, unknown>[]
}

ConditionalOption

type ConditionalOption = {
property: string
query: Record<string, unknown>
option: RHDOptions
}

type RHDOptions = {
hidden?: boolean;
hiddenOnUpdate?: boolean;
hiddenOnInsert?: boolean;
} & {
readOnly?: boolean;
readOnlyOnUpdate?: boolean;
readOnlyOnInsert?: boolean;
} & {
disabled?: boolean;
disabledOnUpdate?: boolean;
disabledOnInsert?: boolean;
}

Condition

type Condition = {
property: string
query: Record<string, unknown>
}

Listens to

eventaction
add-newopens the modal to create a new item, potentially applying default fields from data schema or data provided in the payload of the event
selected-dataopens the modal to edit a selected item, filling in its fields from the data provided in the payload of the event
nested-navigation-state/pushupdates internal representation of the current navigation path by adding one step. The wizard is disabled if the user navigated inside a nested field, and renders a single form with fields of the visualized nested object.
nested-navigation-state/backupdates internal representation of the current navigation path by removing the specified number of steps. The wizard is disabled if the user navigated inside a nested field, and renders a single form with fields of the visualized nested object.
nested-navigation-state/displayupdates internal representation of the current navigation and closes the modal. The wizard is disabled if the user navigated inside a nested field, and renders a single form with fields of the visualized nested object.
successnotifies correct data update as a result of form submission. Payload holds the response of the associated HTTP call and is accessible by action in onSuccess property via response keyword.
errornotifies that something went wrong during form submission. Payload holds the response of the associated HTTP call and is accessible by action in onFail property via response keyword.

Emits

eventdescription
configurable eventproperties such as onFail, onSuccess or actions allow to emit custom events
require-confirmtriggered when trying to close the modal with unsaved data. requireConfirm property allows to customize this behavior
create-datarequests data creation
update-datarequests data update
create-data-with-filerequests data creation and file upload
update-data-with-filerequests data update and file upload