Laravel 10 Livewire Multi Step Form Wizard

Websolutionstuff | Dec-18-2023 | Categories : Laravel

Hello developers! Today, I'm excited to walk you through the process of creating a multi-step form wizard using Laravel 10 and Livewire. Multi-step forms are a fantastic way to enhance user experience by breaking down complex forms into more manageable sections.

With the power of Laravel and the interactivity of Livewire, we'll be able to create a seamless and dynamic form-wizard that guides users through the input process step by step.

In this article, we'll create a multi-step form wizard in laravel 10 Livewire. Also, you can use laravel 10 livewire wizard form in Laravel 8, and Laravel 9.

Step 1: Set Up Laravel Project

If you haven't already, let's start by creating a new Laravel project. Open your terminal and run the following commands:

composer create-project --prefer-dist laravel/laravel livewire-multi-step-form
cd livewire-multi-step-form

 

Step 2: Install Livewire

Next, let's install Livewire into our Laravel project. Run the following command:

composer require livewire/livewire

 

Step 3: Create Migration and Model

Run the following command to generate a migration file for the "products" table:

php artisan make:migration create_products_table

Open the generated migration file in the database/migrations directory. Add the necessary columns to store user data. Here's an example:

Migration:

<?php
  
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
  
class CreateProductcTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('products', function (Blueprint $table) {
            $table->id();
            $table->string('name')->nullable();
            $table->longText('description')->nullable();
            $table->float('amount')->nullable();
            $table->boolean('status')->default(0);
            $table->integer('stock')->default(0);
            $table->timestamps();
        });
    }
  
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('products');
    }
}

Run the migration to create the "products" table:

php artisan migrate

Generate a model for the "Product" table:

php artisan make:model Product

app/Models/Product.php

<?php
  
namespace App\Models;
  
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
  
class Product extends Model
{
    use HasFactory;
 
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'amount', 'description', 'status', 'stock'
    ];
}

 

 

Step 4: Create Livewire Component

 Now, let's generate a Livewire component for our multi-step form. Run:

php artisan make:livewire MultiStepForm

This command will create a MultiStepForm.php file in the app/Http/Livewire directory.

app/Http/Livewire/MultiStepForm.php
resources/views/livewire/multi-step-form.blade.php

Open the app/Http/Livewire/MultiStepForm.php file.

<?php
  
namespace App\Http\Livewire;
  
use Livewire\Component;
use App\Models\Product;
  
class MultiStepForm extends Component
{
    public $currentStep = 1;
    public $name, $amount, $description, $status = 1, $stock;
    public $successMessage = '';
  
    /**
     * Write code on Method
     *
     * @return response()
     */
    public function render()
    {
        return view('livewire.multi-step-form');
    }
  
    /**
     * Write code on Method
     *
     * @return response()
     */
    public function firstStepSubmit()
    {
        $validatedData = $this->validate([
            'name' => 'required|unique:products',
            'amount' => 'required|numeric',
            'description' => 'required',
        ]);
 
        $this->currentStep = 2;
    }
  
    /**
     * Write code on Method
     *
     * @return response()
     */
    public function secondStepSubmit()
    {
        $validatedData = $this->validate([
            'stock' => 'required',
            'status' => 'required',
        ]);
  
        $this->currentStep = 3;
    }
  
    /**
     * Write code on Method
     *
     * @return response()
     */
    public function submitForm()
    {
        Product::create([
            'name' => $this->name,
            'amount' => $this->amount,
            'description' => $this->description,
            'stock' => $this->stock,
            'status' => $this->status,
        ]);
  
        $this->successMessage = 'Product Created Successfully.';
  
        $this->clearForm();
  
        $this->currentStep = 1;
    }
  
    /**
     * Write code on Method
     *
     * @return response()
     */
    public function back($step)
    {
        $this->currentStep = $step;    
    }
  
    /**
     * Write code on Method
     *
     * @return response()
     */
    public function clearForm()
    {
        $this->name = '';
        $this->amount = '';
        $this->description = '';
        $this->stock = '';
        $this->status = 1;
    }
}

Update your resources/views/multi-step-form.blade.php file to include Livewire actions for form navigation and submission.

<div>
 <h6>Laravel 10 Livewire Multi Step Form Wizard - Websolutionstuff</h6>  
@if(!empty($successMessage))
<div class="alert alert-success">
   {{ $successMessage }}
</div>
@endif
  
<div class="stepwizard">
    <div class="stepwizard-row setup-panel">
        <div class="stepwizard-step">
            <a href="#step-1" type="button" class="btn btn-circle {{ $currentStep != 1 ? 'btn-default' : 'btn-primary' }}">1</a>
            <p>Step 1</p>
        </div>
        <div class="stepwizard-step">
            <a href="#step-2" type="button" class="btn btn-circle {{ $currentStep != 2 ? 'btn-default' : 'btn-primary' }}">2</a>
            <p>Step 2</p>
        </div>
        <div class="stepwizard-step">
            <a href="#step-3" type="button" class="btn btn-circle {{ $currentStep != 3 ? 'btn-default' : 'btn-primary' }}" disabled="disabled">3</a>
            <p>Step 3</p>
        </div>
    </div>
</div>
  
    <div class="row setup-content {{ $currentStep != 1 ? 'displayNone' : '' }}" id="step-1">
        <div class="col-xs-12">
            <div class="col-md-12">
                <h3> Step 1</h3>
  
                <div class="form-group">
                    <label for="title">Product Name:</label>
                    <input type="text" wire:model="name" class="form-control" id="taskTitle">
                    @error('name') <span class="error">{{ $message }}</span> @enderror
                </div>
                <div class="form-group">
                    <label for="description">Product Amount:</label>
                    <input type="text" wire:model="amount" class="form-control" id="productAmount"/>
                    @error('amount') <span class="error">{{ $message }}</span> @enderror
                </div>
  
                <div class="form-group">
                    <label for="description">Product Description:</label>
                    <textarea type="text" wire:model="description" class="form-control" id="taskDescription">{{{ $description ?? '' }}}</textarea>
                    @error('description') <span class="error">{{ $message }}</span> @enderror
                </div>
  
                <button class="btn btn-primary nextBtn btn-lg pull-right" wire:click="firstStepSubmit" type="button" >Next</button>
            </div>
        </div>
    </div>
    <div class="row setup-content {{ $currentStep != 2 ? 'displayNone' : '' }}" id="step-2">
        <div class="col-xs-12">
            <div class="col-md-12">
                <h3> Step 2</h3>
  
                <div class="form-group">
                    <label for="description">Product Status</label><br/>
                    <label class="radio-inline"><input type="radio" wire:model="status" value="1" {{{ $status == '1' ? "checked" : "" }}}> Active</label>
                    <label class="radio-inline"><input type="radio" wire:model="status" value="0" {{{ $status == '0' ? "checked" : "" }}}> DeActive</label>
                    @error('status') <span class="error">{{ $message }}</span> @enderror
                </div>
  
                <div class="form-group">
                    <label for="description">Product Stock</label>
                    <input type="text" wire:model="stock" class="form-control" id="productAmount"/>
                    @error('stock') <span class="error">{{ $message }}</span> @enderror
                </div>
  
                <button class="btn btn-primary nextBtn btn-lg pull-right" type="button" wire:click="secondStepSubmit">Next</button>
                <button class="btn btn-danger nextBtn btn-lg pull-right" type="button" wire:click="back(1)">Back</button>
            </div>
        </div>
    </div>
    <div class="row setup-content {{ $currentStep != 3 ? 'displayNone' : '' }}" id="step-3">
        <div class="col-xs-12">
            <div class="col-md-12">
                <h3> Step 3</h3>
  
                <table class="table">
                    <tr>
                        <td>Product Name:</td>
                        <td><strong>{{$name}}</strong></td>
                    </tr>
                    <tr>
                        <td>Product Amount:</td>
                        <td><strong>{{$amount}}</strong></td>
                    </tr>
                    <tr>
                        <td>Product status:</td>
                        <td><strong>{{$status ? 'Active' : 'DeActive'}}</strong></td>
                    </tr>
                    <tr>
                        <td>Product Description:</td>
                        <td><strong>{{$description}}</strong></td>
                    </tr>
                    <tr>
                        <td>Product Stock:</td>
                        <td><strong>{{$stock}}</strong></td>
                    </tr>
                </table>
  
                <button class="btn btn-success btn-lg pull-right" wire:click="submitForm" type="button">Finish!</button>
                <button class="btn btn-danger nextBtn btn-lg pull-right" type="button" wire:click="back(2)">Back</button>
            </div>
        </div>
    </div>
</div>

 

 

Step 5: Set Up Routes

Open the routes/web.php file and add the following route:

Route::get('multi-step-form', function () {
    return view('default');
});

 

Step 6: Design Multi-Step Blade View

Now, we'll create a blade file. In this file we'll use @livewireStyles, @livewireScripts and @livewire('wizard').

resources/views/default.blade.php

<!DOCTYPE html>
<html>
<head>
    <title>how to create multi step form wizard in laravel 10 livewire - websolutionstuff</title>
    @livewireStyles
    <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <link href="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
    <script src="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>
  
    <link href="{{ asset('multi-step-form.css') }}" rel="stylesheet" id="bootstrap-css">
</head>
<body>
    
<div class="container">
    
    <div class="card">
      <div class="card-header">
        how to create multi step form wizard in laravel 10 livewire - websolutionstuff
      </div>
      <div class="card-body">
        <livewire:multi-step-form />
      </div>
    </div>
        
</div>
    
</body>
 
@livewireScripts
  
</html>

public/multi-step-form.css

body{ 
    margin-top:40px; 
}
.stepwizard-step p {
    margin-top: 10px;
}
.stepwizard-row {
    display: table-row;
}
.stepwizard {
    display: table;
    width: 100%;
    position: relative;
}
.stepwizard-step button[disabled] {
    opacity: 1 !important;
    filter: alpha(opacity=100) !important;
}
.stepwizard-row:before {
    top: 14px;
    bottom: 0;
    position: absolute;
    content: " ";
    width: 100%;
    height: 1px;
    background-color: #ccc;
    z-order: 0;
}
.stepwizard-step {
    display: table-cell;
    text-align: center;
    position: relative;
}
.btn-circle {
  width: 30px;
  height: 30px;
  text-align: center;
  padding: 6px 0;
  font-size: 12px;
  line-height: 1.428571429;
  border-radius: 15px;
}
.displayNone{
  display: none;
}

 

Step 7: Run Laravel 10 Application

Run the laravel 10 livewire application using the following command. 

php artisan serve

 

Conclusion:

Congratulations! You've now created a Laravel 10 Livewire multi-step form wizard. This interactive form will guide your users seamlessly through each step, providing a more engaging and user-friendly experience.

 


You might also like:

Recommended Post
Featured Post
How To Install Tailwind CSS In Laravel 9
How To Install Tailwind CSS In...

In this article, we will see how to install tailwind CSS in laravel 9. Tailwind CSS works by scanning all of y...

Read More

Jun-13-2022

Laravel 8 PDF Generate Example
Laravel 8 PDF Generate Example

In this article, we will see a laravel 8 pdf generate example. For generating PDF file we will use the laravel-dompdf pa...

Read More

Oct-17-2020

How To Check Image Blur Or Not Using Python
How To Check Image Blur Or Not...

In this article, we will see how to check image blur or not using python. For blur image check we are using the OpenCV p...

Read More

May-13-2022

How To Setup And Configuration Angular 15
How To Setup And Configuration...

Setting up and configuring Angular 15, the latest version of the popular JavaScript framework, is a crucial step in star...

Read More

Jun-07-2023