@page "/wizard" Multi-step wizard ยท Borm

Multi-step wizard

Group fields into steps. Each step validates before advancing, and steps can be shown conditionally โ€” the company step here only appears for business accounts.

Walk to the last step and then click back through the stepper. Every step you have already been past stays clickable in both directions โ€” it was validated on the way through, so making you press Next through the rest just to fix one answer would be busywork. A step you have never reached stays inert.
Live form
@if (_submitted) {
All done โœ“
@_json
}
View source
@Source
@code { private const string Source = """ @page "/wizard" @code { private readonly AccountSignup _model = new(); private BormDefinition _schema = default!; protected override void OnInitialized() { _schema = BormBuilder.For() .Title("Account setup") .Field(x => x.FullName, f => f.Required().MinLength(2)) .Field(x => x.Email, f => f.Required().Email()) .Field(x => x.AccountKind, f => f.AsRadio().Label("Account type")) .Field(x => x.CompanyName, f => f.Label("Company name").Required("Required for business accounts.")) .Field(x => x.VatNumber, f => f.Label("VAT number")) .Field(x => x.AcceptTerms, f => f.Required("Please accept the terms.")) .Step("contact", s => s.Title("Contact").Fields("FullName", "Email")) .Step("type", s => s.Title("Account type").Fields("AccountKind")) .Step("company", s => s.Title("Company") .Fields("CompanyName", "VatNumber") .VisibleWhen(new BormFieldCondition("AccountKind", BormConditionOperator.Equals, "Business"))) .Step("confirm", s => s.Title("Confirm").Fields("AcceptTerms")) .Build(); } private void HandleSubmit(BormState state) { var json = System.Text.Json.JsonSerializer.Serialize(_model, new System.Text.Json.JsonSerializerOptions { WriteIndented = true }); } } """; private readonly AccountSignup _model = new(); private BormDefinition _schema = default!; private bool _submitted; private string _json = ""; protected override void OnInitialized() { _schema = BormBuilder.For() .Title("Account setup") .Field(x => x.FullName, f => f.Required().MinLength(2)) .Field(x => x.Email, f => f.Required().Email()) .Field(x => x.AccountKind, f => f.AsRadio().Label("Account type")) .Field(x => x.CompanyName, f => f.Label("Company name").Required("Required for business accounts.")) .Field(x => x.VatNumber, f => f.Label("VAT number")) .Field(x => x.AcceptTerms, f => f.Required("Please accept the terms.")) .Step("contact", s => s.Title("Contact").Fields("FullName", "Email")) .Step("type", s => s.Title("Account type").Fields("AccountKind")) .Step("company", s => s.Title("Company") .Fields("CompanyName", "VatNumber") .VisibleWhen(new BormFieldCondition("AccountKind", BormConditionOperator.Equals, "Business"))) .Step("confirm", s => s.Title("Confirm").Fields("AcceptTerms")) .Build(); } private void HandleSubmit(BormState state) { _submitted = true; _json = System.Text.Json.JsonSerializer.Serialize(_model, new System.Text.Json.JsonSerializerOptions { WriteIndented = true }); } }