A step represents a single screen in a flow. It is made up of schemas, which represent data to be collected from the user, layouts which describe how the screen looks, and a number of advanced features to provide more complex behaviors.
Steps and Flows are stateless. If you want to persist data across steps without using a session in your backend, you can include any extra data you want submitted in the step you send to the client.
The model property will pre-fill matching schema values into your step.
val filledDetails = Step.build {
id = "filledDetails"
title = "Are these details correct?"
schemas {
obj {
id = "#schema"
properties {
string("name") {
title = "Name"
}
string("phone") {
title = "Phone"
control = Control.Schema.String.PHONE_NUMBER
}
obj("address") {
title = "Address"
properties {
string("line1") {
title = "Line 1"
}
string("city") {
title = "City"
}
string("postcode") {
title = "Postcode"
}
}
}
}
}
}
model = encodeToJsonElement(
mapOf(
"name" to "John Smith",
"phone" to "+123456789",
"address" to mapOf(
"line1" to "123 Baker Street",
"city" to "London",
"postcode" to "N1 1AA"
)
)
)
layout {
form {
schemaId = "#schema"
}
}
}If you want to include data that isn't shown on the screen, you need a schema which is either hidden or unreferenced (not laid out on the screen in a FormLayout). You can then add the required data to the model. Showing and hiding schemas and gradually adding data is one way to build up a data model over multiple steps.
val contactDetailsExample = Step.build {
id = "contactDetails"
title = ""
schemas {
obj {
id = "#address"
title = "Address"
properties {
string("line1") {
title = "Address Line 1"
}
string("postcode") {
title = "Postcode"
}
}
}
obj {
id = "#contact"
title = "Contact details"
properties {
string("name") {
title = "Name"
hidden = true
}
string("phone") {
title = "Phone number"
control = Control.Schema.String.PHONE_NUMBER
}
string("email") {
title = "Email"
}
}
}
}
layout {
form {
schemaId = "#contact"
}
button {
title = "Continue"
behavior = ActionBehavior.build {
action {
url = "/submit"
}
}
}
}
model = encodeToJsonElement(
mapOf(
"name" to "John Smith",
"line1" to "123 Baker Street",
"postcode" to "N1 1AA"
)
)
}A response is determined to be a Step when the status code is in the 200-299 range, the exit property in the triggering action was not set to true, and the X-DF-Response-Type: step header is provided.
| Property | Type | Required | Description |
|---|---|---|---|
analytics | Map<String, String> | No | Additional data to be included in analytics events. The keys/values in this object will be included in all events generated by clients. |
| String | No | Specify a particular control to instruct how the step should be rendered. If the control is unknown, it will be ignored.
|
description | String | No | A user-facing subtitle. |
errors | StepError | No | Errors which will be shown when the step loads. |
external | External | No | Used to configure an app or web page to be opened when the step is first loaded. |
| Array<Layout> | No | A layout which should occupy the footer of the step. If the client doesn't support a separate footer, this content will appear as if it was appended to the layout array.
|
id | String | Yes | An identifier which is added to analytics events as stepId. |
layout | Array<Layout> | Yes | An array of layouts describing how the step should be structured. |
linkHandlers | Array<LinkHandler> | No | Used to configure deep/universal link handling, allowing the flow to progress based on incoming redirects/links. |
model | Any | No | The data to use when initialising the step. It must follow the structure the schemas array describes, and any data which doesn't correspond to the schema is ignored. |
| No | Used to configure navigational behavior of the step, for example to provide an Action to perform when navigating back.
| |
polling | Polling | No | Used to configure a polling behavior, allowing the flow to progress automatically. |
| String | No | Must be an ISO 8601 formatted string. After this time has passed, the step will be refreshed. It should include date, time, and timezone.
|
refreshUrl | String | No | The URL to use to fetch an updated step when a Refresh Behavior is triggered, or when the value of a schema marked 'refreshStepOnChange' is updated. |
schemas | Array<Schema> | Yes | An array of schemas describing the data for the user to input. Each root schemas which should be displayed to the user must be referenced by a Form Layout in the layout property. If a schema is not referenced by a Form Layout, it won't be displayed, but it will still be submitted. On submission, the values corresponding to each element in the schemas array will be merged, as if they were contained in an All Of Schema. |
| Array<String> | No | An optional list of identifiers used to configure renderers.
|
title | String | Yes | A user-facing title. |
| No | An optional toolbar to be displayed at the top of the step. See Toolbar.
|
splash
Display the step with centered aligned content.
val splashStepExample = Step.build {
id = "splash"
title = ""
control = Control.Step.SPLASH
layout {
media {
media = Media.Image.build {
uri = "urn:wise:illustrations:megaphone"
}
}
heading {
text = "Success!"
control = Control.Layout.Heading.DISPLAY
align = Align.CENTER
}
paragraph {
text = "Congratulations! Everything went... according to plan."
align = Align.CENTER
margin = Size.XL
}
}
footer {
button {
title = "Continue"
control = Control.Layout.Button.PRIMARY
behavior = ActionBehavior.build {
action {
exit = true
}
}
}
}
}splash-celebration
Display the step in a celebration context.
val splashCelebrationStepExample = Step.build {
id = "splashcelebration"
title = ""
control = Control.Step.SPLASH_CELEBRATION
layout {
media {
media = Media.Image.build {
uri = "urn:wise:illustrations:plane?+type=animated"
}
}
heading {
text = "Success!"
control = Control.Layout.Heading.DISPLAY
align = Align.CENTER
}
paragraph {
text = "Congratulations! Everything went... according to plan."
align = Align.CENTER
margin = Size.XL
}
}
footer {
button {
title = "Continue"
control = Control.Layout.Button.PRIMARY
behavior = ActionBehavior.build {
action {
exit = true
}
}
}
}
}