Skip to content

Multi-Step Forms

StepForm creates multi-step wizard flows where each step is a complete Form. It supports sequential navigation, progress tracking, draft saving, and custom layouts.

Basic StepForm

dart
final stepForm = StepForm(
  title: 'Certification Application',
  steps: [
    FormBuilder(title: 'Eligibility')
      .text('applicant_name', title: 'Full Name').required()
      .text('email', title: 'Email').required().email()
      .select('experience_level', title: 'Experience Level')
        .option('junior', title: 'Junior (0-2 years)')
        .option('mid', title: 'Mid (2-5 years)')
        .option('senior', title: 'Senior (5+ years)')
        .required()
      .build(),

    FormBuilder(title: 'Course History')
      .select('completed_courses', title: 'Completed Courses')
        .option('CS101', title: 'Intro to CS')
        .option('CS201', title: 'Data Structures')
        .option('CS301', title: 'Algorithms')
        .multiple()
        .required('Select at least one course')
      .number('total_hours', title: 'Total Study Hours')
        .integerOnly()
        .min(40, message: 'Minimum 40 hours required')
        .required()
      .build(),

    FormBuilder(title: 'Exam Scheduling')
      .dateTime('exam_date', title: 'Preferred Exam Date')
        .dateOnly()
        .required()
      .select('exam_center', title: 'Exam Center')
        .option('center_a', title: 'Downtown Center')
        .option('center_b', title: 'University Campus')
        .option('center_c', title: 'Online Proctored')
        .required()
      .boolean('accommodations', title: 'Request Accommodations')
      .text('accommodation_details', title: 'Accommodation Details')
        .showWhen(When.fieldTrue('accommodations'))
        .multiline(3)
      .build(),

    FormBuilder(title: 'Review & Submit')
      .boolean('confirm_accuracy', title: 'I confirm all information is accurate')
        .required('You must confirm accuracy')
      .boolean('accept_policies', title: 'I accept the examination policies')
        .required('You must accept the policies')
      .build(),
  ],
  isSequential: true,
  trackProgress: ProgressTrackingType.required,
  allowDrafts: true,
  showStepStatus: true,
);

Configuration Options

Sequential vs Non-Sequential

dart
// Sequential: must complete steps in order
StepForm(
  isSequential: true,  // Can't skip to step 3 without completing 1 and 2
  steps: [...],
)

// Non-sequential: can navigate freely
StepForm(
  isSequential: false,  // User can jump to any step
  steps: [...],
)

Progress Tracking

dart
StepForm(
  trackProgress: ProgressTrackingType.none,     // No tracking
  trackProgress: ProgressTrackingType.all,      // Track all fields
  trackProgress: ProgressTrackingType.required, // Track required fields only
  steps: [...],
)

Draft Support

dart
StepForm(
  allowDrafts: true,  // Users can save partial progress
  steps: [...],
)

Submit Action

dart
StepForm(
  submitAction: Action(...),  // Vyuh Action to execute on final submit
  steps: [...],
)

Layouts

StepForm supports multiple layout configurations:

Default Layout

Horizontal step indicator with animated transitions between steps:

dart
StepForm(
  layout: DefaultStepFormLayout(),
  steps: [...],
)

Vertical Stepper

Material Design vertical stepper layout:

dart
StepForm(
  layout: VerticalStepperStepFormLayout(),
  steps: [...],
)

Single Step Layout

Shows one step at a time without a step indicator:

dart
StepForm(
  layout: SingleStepLayout(),
  steps: [...],
)

Custom Controllers

StepForm uses a StepFormControllerConfiguration to manage step navigation and state. The default is NoOpController, but you can register custom controllers:

dart
StepFormDescriptor(
  controllers: [
    MyPersistentController.typeDescriptor,
  ],
)

Working with Step Values

Each step is a separate Form with its own FormGroup. To collect all values:

dart
// Each step has its own values
final step1Values = stepForm.steps[0].currentValues;
final step2Values = stepForm.steps[1].currentValues;

// Combine all step values
final allValues = <String, dynamic>{};
for (final step in stepForm.steps) {
  allValues.addAll(step.currentValues);
}

Validating Steps

Each step validates independently:

dart
// Validate current step before advancing
final currentStep = stepForm.steps[currentIndex];
if (currentStep.validate()) {
  // Move to next step
  currentIndex++;
} else {
  // Show errors on current step
}

LMS Example: Certification Application

A 4-step certification application:

Step 1 -- Eligibility: Name, email, experience level, verifying minimum requirements.

Step 2 -- Course History: Multi-select completed courses, total study hours with minimum threshold.

Step 3 -- Exam Scheduling: Date picker with business hours validation, exam center selection, optional accommodation request with conditional detail field.

Step 4 -- Review: Confirmation checkboxes for accuracy and policy acceptance.

Each step validates before allowing navigation to the next, and the progress indicator shows completion status based on required fields.

Next Steps