Laravel 9 Livewire Multi Step Form Wizard Tutorial

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.

Installing fresh new Laravel 9 Application
Installing fresh new Laravel 9 Application

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).

Creating Database
Creating Database

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=
Database Configuration - Laravel 9 Livewire Multi Step Form Wizard Tutorial
Database Configuration

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');
    }
};
Creating Products Migration - Laravel 9 Livewire Multi Step Form Wizard Tutorial
Creating Products Migration

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'
    ];
}
Creating Product Model - Laravel 9 Livewire Multi Step Form Wizard Tutorial
Creating Product Model

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');
});
Creating Route - Laravel 9 Livewire Multi Step Form Wizard Tutorial
Creating Route

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:

Laravel 9 Livewire Multi Step Form Wizard Tutorial
Laravel 9 Livewire Multi Step Form Wizard Tutorial

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: Create Custom Artisan Command Laravel 9 Example

4 Comments

Leave a Reply