Creating steps
Similar to a Page
, grouping can be achieved by using the Step
class.
Other than with pages, with steps the developer can dictate the order of pages to be visited: the user is not able to
move freely between pages but moves to the next/previous step with a next/previous button. Page
and Step
cannot be
combined within a single parametrization.
A Step
is defined in the parametrization similar to a Page
. The labels of the next and previous buttons can be set
per step:
import viktor as vkt
class Parametrization(vkt.Parametrization):
step_1 = vkt.Step('Step 1 - without views')
step_1.input_1 = vkt.TextField('This is a text field')
step_1.input_2 = vkt.NumberField('This is a number field')
step_2 = vkt.Step('Step 2 - with views', views=['geometry_view', 'data_view'])
step_2.input_1 = vkt.TextField('This is a text field')
step_2.input_2 = vkt.NumberField('This is a number field')
Step 1 with no views
When navigating to step 2, you will see that the two views will be present:
Step 2 with a GeometryView and a DataView
Button labels
The labels of the previous and next buttons can be set per step:
vkt.Step('Step 2', previous_label='Go to step 1', next_label='Go to step 3')
Validation of user input
When implementing the on_next
argument, the corresponding function is called when a user clicks the 'next' button to
move to the next step. This can be used to, for example, validate the input of the current active step. Please note that
the validation function cannot take longer than 3 seconds!
import viktor as vkt
def validate_step_1(params, **kwargs):
if params.step_1.width > params.step_1.height:
raise vkt.UserError("The design is not feasible")
class Parametrization(vkt.Parametrization):
step_1 = vkt.Step('Step 1', on_next=validate_step_1)
step_1.width = vkt.NumberField('Width')
step_1.height = vkt.NumberField('Height')
Generic constraints (e.g. min
on a NumberField
) are
automatically validated by the platform.
Additionally, fields can be marked as invalid.
All individual kwargs
can be added explicitly in the signature if needed:
def validate_step_1(params, entity_id, entity_name, workspace_id, **kwargs):
...
Disabling a step
Disabling a Step can be done by setting the enabled
argument, similar to hiding a field:
- By using a BooleanField
vkt.Step("Step 2", enabled=vkt.Lookup("step_1.param_x"))
- By using a callback function
def get_enabled(params, **kwargs):
return params.step_1.param_y > 5
vkt.Step("Step 2", enabled=get_enabled)
- Depending on other field(s)
_step_enabled = vkt.And(
vkt.IsFalse(vkt.Lookup('step_1.param_x')),
vkt.IsEqual(vkt.Lookup('step_1.param_y'), 5)
)
step = vkt.Step("Step 2", enabled=_step_enabled)
When a step is disabled, it will be skipped when the user clicks the "next step" button. The step number will remain visible, as a visual cue that there is a skipped step.
In some cases you may have steps that depend on user input. For example, "Step 2(a)" for calculations about a stone house, and "Step 2(b)" for calculations about a glass house. In such cases, we recommend to merge them into one step (e.g. "Calculations") and use tab visibility to hide the tab/fields that you do not need, within the step. This will lead to a more consistent flow through the steps for the end user.
Adjust the parametrization width
A separate parametrization width per Step can be defined by specifying the width
argument:
import viktor as vkt
class Parametrization(vkt.Parametrization):
step_1 = vkt.Step("Step 1", width=30)
...
step_2 = vkt.Step("Step 2", width=70)
...
When the width
is defined both on the Parametrization class and a Step, the width of the Step will take precendence while
the global width is used for steps that have not defined a specific width. For more detail on the global parametrization width
and rules with respect to a field's flex
argument, please refer to this page.