Hello Dev, In this tutorial we are going to learn Laravel 9 Livewire Multi Step Form Wizard Tutorial. This tutorial will cover on how to create a Livewire Multi Step Form wizard in laravel 9 application.
Laravel Livewire is a library that makes it simple to build modern, reactive, dynamic interfaces using Laravel Blade as your templating language. This is a great stack to choose if you want to build an application that is dynamic and reactive but don’t feel comfortable jumping into a full JavaScript framework like Vue.
Steps for Laravel 9 Livewire Multi Step Form Wizard Tutorial:
- Step 1: Installing fresh new Laravel 9 Application
- Step 2: Creating Database and Configuration
- Step 3: Creating Migration and Model
- Step 4: Installing Livewire
- Step 5: Creating Component
- Step 6: Creating Route
- Step 7: Creating View Blade File and CSS
- Step 8: Testing
- Step 9: Conclusion
Also Read: Laravel 9 Livewire Datatables Example
Step 1: Installing fresh new Laravel 9 Application
First, we are installing a fresh new laravel 9 application. To install a laravel application run the following command in terminal.
composer create-project laravel/laravel livewire-multistep
cd livewire-multistep
Note: “livewire-multistep” is our laravel application name.

Step 2: Creating Database and Configuration
Now, we will create a database. First open phpmyadmin and create a database with name “livewire-multistep” (you may use anything you like).

Now we are going to add the database details to the laravel application. Open .env file and enter the database details.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=livewire-multistep
DB_USERNAME=root
DB_PASSWORD=

Step 3: Creating Migration and Model
Now its time to create a products migration file for our laravel application. Run the following command to create a products migration file.
php artisan make:migration create_products_table
And add the following fields to the migration file.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class 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');
}
};

Then run the migration by following command.
php artisan migrate
Now, Lets create a Product Model. Run the following command to create a Product model.
php artisan make:model Product
And update the product model with the following.
<?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: Installing Livewire
In this step, we are installing Livewire. Run the following command to install Livewire
composer require livewire/livewire
Also Read: Install NextUI with React Js in Laravel 9
Step 5: Creating Component
Now, we will create component file. Run the following command to create a component file.
php artisan make:livewire wizard
The above command will create a two file:
- app/Http/Livewire/Wizard.php
- resources/views/livewire/wizard.blade.php
Now update the file with the below code.
app/Http/Livewire/Wizard.php
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use App\Models\Product;
class Wizard 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.wizard');
}
/**
* 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;
}
}
resources/views/livewire/wizard.blade.php
<div>
@if(!empty($successMessage))
<div class="alert alert-success">
{{ $successMessage }}
</div>
@endif
<div class="text-center">
<!-- progressbar -->
<ul class="progressbar">
<li class="{{ $currentStep != 1 ? '' : 'active' }}"><a href="#step-1" type="button">Step 1</a></li>
<li class="{{ $currentStep != 2 ? '' : 'active' }}"><a href="#step-2" type="button">Step 2</a></li>
<li class="{{ $currentStep != 3 ? '' : 'active' }}"><a href="#step-3" type="button" disabled="disabled">Step 3</a></li>
</ul>
</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>
Also Read: Laravel 9 Install Vue JS Example
Step 6: Creating Route
Now create a route for our laravel application. Open routes/web.php and add the following route.
<?php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
Route::get('wizard', function () {
return view('default');
});

Step 7: Creating View Blade File and CSS
Now create view blade file which we call from our route. Create a default.blade.php inside resources/views and add the following code.
<!DOCTYPE html>
<html>
<head>
<title>Laravel 9 Livewire Multi Step Form Wizard Tutorial - LaravelTuts.com</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('css/wizard.css') }}" rel="stylesheet" id="bootstrap-css">
</head>
<body>
<div class="container">
<div class="card">
<div class="card-header">
Laravel 9 Livewire Multi Step Form Wizard Tutorial - LaravelTuts.com
</div>
<div class="card-body">
<livewire:wizard />
</div>
</div>
</div>
@livewireScripts
</body>
</html>
Now create new css file wizard.css inside public/css and add the following style.
body{
margin-top:40px;
}
/*progressbar*/
.progressbar {
overflow: hidden;
/*CSS counters to number the steps*/
counter-reset: step;
width: 60%;
margin: 0 auto 30px;
}
.progressbar li {
list-style-type: none;
color: white;
text-transform: uppercase;
font-size: 18px;
width: 33.33%;
float: left;
position: relative;
text-decoration: none;
}
.progressbar li a:hover{
text-decoration: none;
}
.progressbar li:before {
content: counter(step);
counter-increment: step;
width: 50px;
line-height: 50px;
display: block;
font-size: 18px;
font-weight: bold;
color: #333;
background: #eeeeee;
border-radius: 50%;
margin: 0 auto 5px auto;
}
/*progressbar connectors*/
.progressbar li:after {
content: '';
width: 100%;
height: 2px;
background: white;
position: absolute;
left: -50%;
top: 9px;
z-index: -1; /*put it behind the numbers*/
}
.progressbar li:first-child:after {
/*connector not needed before the first step*/
content: none;
}
/*marking active/completed steps green*/
/*The number of the step and the connector before it = green*/
.progressbar li.active:before, .progressbar li.active:after {
background: rgb(255,99,71);
color: white;
}
.displayNone{
display: none;
}
Also Read: React JS Image Upload using Vite in Laravel 9 Example
Step 8: Testing
Now its time to test our laravel 9 application. Run the following command to start the laravel server.
php artisan serve
And open the following URL in any web browser.
http://127.0.0.1:8000/wizard
Preview:

Step 9: Conclusion
Today, We had learn Laravel 9 Livewire Multi Step Form Wizard Tutorial. Hope this tutorial helped you with learning Laravel 9. If you have any question you can ask us at comment section below. If you like the tutorial please subscribe our YouTube Channel and follow us on social network Facebook and Instagram.
[…] Also Read: Laravel 9 Livewire Multi Step Form Wizard Tutorial […]
[…] Also Read: Laravel 9 Livewire Multi Step Form Wizard Tutorial […]
[…] Also Read: Laravel 9 Livewire Multi Step Form Wizard Tutorial […]
[…] Also Read: Laravel 9 Livewire Multi Step Form Wizard Tutorial […]