Hone logo
Hone
Problems

Building a Multi-Step Form in Vue.js with TypeScript

This challenge focuses on implementing a robust and user-friendly multi-step form within a Vue.js application using TypeScript. Multi-step forms are crucial for breaking down complex data collection into manageable stages, improving user experience and reducing form abandonment. You will create a reusable component that can handle different numbers of steps and manage form data across these steps.

Problem Description

Your task is to create a Vue.js component, MultiStepForm, that renders a form spread across multiple distinct steps. The component should manage the current step, navigate between steps, and accumulate form data from each step.

Key Requirements:

  1. Step Management:

    • The component should accept an array of step configurations. Each step configuration should include a title (for display, e.g., in a stepper navigation) and a component (a Vue component to render for that step).
    • The form should display only the content of the current step.
    • Navigation buttons ("Next", "Previous", "Submit") should be dynamically displayed based on the current step.
    • The "Next" button should be disabled if the current step's form is invalid (you'll need a mechanism to validate each step).
    • The "Previous" button should navigate back to the previous step.
    • The "Submit" button should appear on the last step and trigger a final submission event.
  2. Data Accumulation:

    • The component should maintain a single data object that accumulates all the data entered by the user across all steps.
    • When navigating between steps, the data from the current step should be saved into the main data object.
  3. Validation:

    • Each individual step component should be responsible for its own validation. The MultiStepForm component should provide a way for step components to signal their validity (e.g., by returning a boolean from a validate method or emitting an event). For this challenge, assume each step component will have a validate method that returns true if valid, false otherwise.
  4. TypeScript Integration:

    • All components and types should be written in TypeScript.
    • Define clear interfaces for step configurations and the overall form data structure.
  5. Reusability:

    • The MultiStepForm component should be general enough to be used with different sets of step components and data structures.

Expected Behavior:

  • When the form loads, the first step is displayed.
  • Clicking "Next" moves to the subsequent step, saving the current step's data.
  • Clicking "Previous" moves back to the prior step, retaining previously entered data.
  • The "Next" button is enabled only when the current step's validation passes.
  • On the last step, "Next" is replaced by "Submit".
  • Clicking "Submit" triggers a custom event (onSubmit) on the MultiStepForm component, passing the accumulated form data.

Edge Cases:

  • A form with only one step.
  • Handling validation errors gracefully, possibly by highlighting invalid fields within the step component.

Examples

Let's consider a simple user registration form with three steps:

  • Step 1: Personal Information (Name, Email)
  • Step 2: Address Information (Street, City, Zip Code)
  • Step 3: Account Setup (Username, Password)

Example 1: Initial State

Input:
A user loads the MultiStepForm.
The form configuration defines 3 steps: PersonalInfo, AddressInfo, AccountSetup.

Output:
The 'PersonalInfo' component is rendered.
"Previous" button is disabled.
"Next" button is enabled (assuming initial data is valid or no validation required on empty).
Current step indicator shows "Step 1 of 3".

Example 2: Navigating to Step 2

Input:
User fills in "John Doe" for Name and "john.doe@example.com" for Email in Step 1.
User clicks "Next".

Output:
The 'AddressInfo' component is rendered.
The form data object now contains: { name: "John Doe", email: "john.doe@example.com" }.
"Previous" button is enabled.
"Next" button is enabled (assuming initial data is valid or no validation required on empty).
Current step indicator shows "Step 2 of 3".

Example 3: Reaching the End and Submitting

Input:
User has filled all fields in all steps.
User is on Step 3 (Account Setup).
User clicks "Submit".

Output:
A custom event `onSubmit` is emitted from the MultiStepForm component with the following payload:
{
  name: "John Doe",
  email: "john.doe@example.com",
  street: "123 Main St",
  city: "Anytown",
  zipCode: "12345",
  username: "johndoe",
  password: "securepassword"
}

Constraints

  • The MultiStepForm component should be a single Vue component.
  • Step components can be any valid Vue components.
  • Validation logic resides within individual step components.
  • The form should support at least 1 step and a theoretically unlimited number of steps.
  • Form data should be stored as a single JSON-serializable object.

Notes

  • Consider how you will pass data from the MultiStepForm component to the individual step components so they can display pre-filled values.
  • Think about how the MultiStepForm component will receive data back from the step components when they are updated.
  • For validation, each step component should expose a method (e.g., validate(): boolean) that the MultiStepForm can call.
  • The structure of the step configuration array is up to you, but it should be well-defined using TypeScript interfaces.
  • A visual indicator for the current step (like a stepper bar) is recommended but not strictly required for the core functionality.
  • You'll need to define the types for your form data. For example, you might have an interface UserData that encompasses data from all steps.
Loading editor...
typescript