Creating Multi-Step Forms with Livewire



Building multi-step forms in web applications can enhance user experience by breaking down long forms into manageable steps. Livewire, a full-stack framework for Laravel, simplifies this process with its reactive components and real-time feedback capabilities. This article will guide you through creating a multi-step form using Livewire.


What is Livewire?


Livewire is a Laravel package that allows you to create dynamic, reactive interfaces using Blade components. It eliminates the need for front-end frameworks like Vue or React by enabling you to write JavaScript-like functionality in PHP.


Getting Started


Before we dive into creating a multi-step form, ensure you have a Laravel project set up with Livewire installed. If not, follow these steps:


1. Create a Laravel Project:


   composer create-project --prefer-dist laravel/laravel livewire-forms

   cd livewire-forms


2. Install Livewire:


   composer require livewire/livewire


3. Add Livewire Scripts to Your Layout:


   In your `resources/views/layouts/app.blade.php` (or any main layout file), include Livewire's scripts and styles.


   <!DOCTYPE html>

   <html>

   <head>

       <title>Livewire Multi-Step Form</title>

       @livewireStyles

   </head>

   <body>

       @yield('content')

       @livewireScripts

   </body>

   </html>


Creating the Multi-Step Form


Step 1: Create the Livewire Component


First, generate a Livewire component:


php artisan make:livewire MultiStepForm


This command creates two files: `MultiStepForm.php` (the component class) and `multi-step-form.blade.php` (the component view).


Step 2: Define the Form Structure


In `app/Http/Livewire/MultiStepForm.php`, define the form steps and the properties for the form data:


<?php


namespace App\Http\Livewire;


use Livewire\Component;


class MultiStepForm extends Component

{

    public $step = 1;

    public $name, $email, $password, $address, $city, $state, $zipcode;


    protected $rules = [

        1 => ['name' => 'required', 'email' => 'required|email'],

        2 => ['password' => 'required|min:6'],

        3 => ['address' => 'required', 'city' => 'required', 'state' => 'required', 'zipcode' => 'required|numeric'],

    ];


    public function render()

    {

        return view('livewire.multi-step-form');

    }


    public function nextStep()

    {

        $this->validate($this->rules[$this->step]);

        $this->step++;

    }


    public function previousStep()

    {

        $this->step--;

    }


    public function submit()

    {

        $this->validate($this->rules[$this->step]);

        // Handle form submission

    }

}


Step 3: Create the Component View


In `resources/views/livewire/multi-step-form.blade.php`, create the form layout with conditional steps:


<div>

    @if ($step === 1)

        <div>

            <label for="name">Name</label>

            <input type="text" wire:model="name" id="name">

            @error('name') <span class="error">{{ $message }}</span> @enderror


            <label for="email">Email</label>

            <input type="email" wire:model="email" id="email">

            @error('email') <span class="error">{{ $message }}</span> @enderror


            <button wire:click="nextStep">Next</button>

        </div>

    @elseif ($step === 2)

        <div>

            <label for="password">Password</label>

            <input type="password" wire:model="password" id="password">

            @error('password') <span class="error">{{ $message }}</span> @enderror


            <button wire:click="previousStep">Back</button>

            <button wire:click="nextStep">Next</button>

        </div>

    @elseif ($step === 3)

        <div>

            <label for="address">Address</label>

            <input type="text" wire:model="address" id="address">

            @error('address') <span class="error">{{ $message }}</span> @enderror


            <label for="city">City</label>

            <input type="text" wire:model="city" id="city">

            @error('city') <span class="error">{{ $message }}</span> @enderror


            <label for="state">State</label>

            <input type="text" wire:model="state" id="state">

            @error('state') <span class="error">{{ $message }}</span> @enderror


            <label for="zipcode">Zipcode</label>

            <input type="text" wire:model="zipcode" id="zipcode">

            @error('zipcode') <span class="error">{{ $message }}</span> @enderror


            <button wire:click="previousStep">Back</button>

            <button wire:click="submit">Submit</button>

        </div>

    @endif

</div>


Step 4: Include the Component in a Blade View


Include the Livewire component in your desired Blade view, such as `resources/views/welcome.blade.php`:


@extends('layouts.app')


@section('content')

    <div class="container">

        @livewire('multi-step-form')

    </div>

@endsection


You now have a basic multi-step form using Livewire in Laravel. This setup can be further extended with more steps, additional validations, and improved UI/UX to suit your application's needs. Livewire's simplicity and reactive nature make it a powerful tool for creating dynamic forms without heavy JavaScript frameworks.