Laravel Livewire CRUD Using Bootstrap Modal Full Example Guideline And Demo Source Code

  • 08-07-2022
  • 3771
  • Laravel 9
  • Haresh Chauhan

Watch Youtube Video (HINDI) :
What is Laravel Livewire?

Laravel livewire is a module library that makes it simple to build an attractive and single-page modern, reactive, dynamic blade file interface that uses a laravel blade file and in your language, you can develop. There is no more jquery or javascript required if your using laravel livewire.

Livewire provides event models and events to take action on the URL.

So today in this post we will learn how to integrate laravel livewire and take a full example to CRUD operation. In this post, I have taken the example of creating a post.

Also, include an output preview at the end of the post, Still, there is a link to download the livewire run operation example source code.

For the design of CRUD operation and create, edit, view, and listing I have taken the help of Bootstrap in this livewire post.

So before starting the development, I want to say you keep following the step given in this example and integrate livewire in your project, It's simple to use and integrate in laravel. just need to press some command for integration in your application.

Step 1: Create Laravel Project

Create your laravel project using the below-suggested command in your terminal.

composer create-project --prefer-dist laravel/laravel Livewire

cd Livewire

Step 2: Install Live Wire Composer

Install composer in your laravel project using the below-given command.

composer require livewire/livewire

Step 3: Database Configuration

Create a database in your database and config in your .env file in the laravel project.

.env

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=livewire
DB_USERNAME=root
DB_PASSWORD=

Step 4: Make Post Model & Migration

In this step, we will create a Post model and its migration to create a post table in the database. So use the below-suggested command and in your root project directory terminal.

This command will create a migration in your migrations file and also will create a post model in models folder inside the app directory of your laravel application.

php artisan make:model Post -m

Step 5: Setting Migration Columns

Using the above command this migration was created in your migration folder, Now we will add some columns in this migration for this Post Crud operation. So follow it in your project and create your migration as per your requirement.

database/migrations

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('post_id')->unique()->nullable();
            $table->string('title')->nullable();
            $table->enum('status',['active','inactive'])->default('inactive');
            $table->text('description')->nullable();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('posts');
    }
}

Step 6: Setting Model

Add all the attribute which you added in your posts table migration file in the Post Model fillable protected array variable.

app/Models/Post.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasFactory;

    protected $fillable = [
        'post_id',
        'title',
        'status',
        'description'
    ];
}

Step 7: Migrate Table

Now, Migrate the migration using the below-suggested command.

php artisan migrate

This will create a posts table inside your database and this we will use do to CRUD operation in laravel livewire.

Step 8: Make Livewire Component

Now, Time to create a livewire basic layout and component.

Use the below given command, This will create a basic layout structure in your resources/views folder.

php artisan make:livewire layouts/base

Use this command, This will create a PostsComponent in your app directory livewire.

php artisan make:livewire PostsComponent

Now, You can see in your resources and livewire folder, that there create that folder and blade file.

Step 9: Add Route

This in step we will define route in web.php file inside the routes folder of laravel application.

Here we just need to define just a single route, Because there is no required more than one page for this livewire CRUD, It is all about in single page whole crud.

routes/web.php

<?php

use App\Http\Livewire\PostsComponent;


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('post', PostsComponent::class);

Step 10: Make Html Design

After Routes, Just copy all below-given content and paste them into your base.blade.php file.

resources/views/livewire/layouts/base.blade.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Webappfix - Laravel Livewire CRUD Example</title>

    {{-- Bootstrap Styles --}}
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css">

    @livewireStyles
</head>
<body>
    {{ $slot }}

    {{-- Bootstrap Scripts --}}
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.min.js"></script>

    @stack('scripts')
    @livewireScripts
</body>
</html>

Step 11: Setting PostsComponent

This is the whole post crud operation controller code in this component if you use another module you can modify it according to your, Here I have taken the example of a post. Just follow the component code.

app/Http/Livewire/PostsComponent.php

<?php

namespace App\Http\Livewire;

use App\Models\Post;
use Livewire\Component;
use phpDocumentor\Reflection\Types\This;

class PostsComponent extends Component
{
    public $post_id, $title, $status, $description, $post_edit_id, $post_delete_id;

    public $view_post_id, $view_post_title, $view_post_status, $view_post_description;

    public $searchTerm;

    //Input fields on update validation
    public function updated($fields)
    {
        $this->validateOnly($fields, [
            'post_id' => 'required|unique:posts,post_id,'.$this->post_edit_id.'', //Validation with ignoring own data
            'title' => 'required',
            'status' => 'required|in:active,inactive',
            'description' => 'required',
        ]);
    }

    public function storePost()
    {
        //on form submit validation
        $this->validate([
            'post_id' => 'required|unique:posts',
            'title' => 'required',
            'status' => 'required|in:active,inactive',
            'description' => 'required',
        ]);

        //Add Data into Post table Data
        $post = new Post();
        $post->post_id = $this->post_id;
        $post->title = $this->title;
        $post->status = $this->status;
        $post->description = $this->description;
        $post->save();

        session()->flash('message', 'New Post addedd Successfully.');

        $this->post_id = '';
        $this->title = '';
        $this->status = '';
        $this->description = '';

        //For hide modal after add posts success
        $this->dispatchBrowserEvent('close-modal');
    }


    public function resetInputs()
    {
        $this->post_id = '';
        $this->title = '';
        $this->status = '';
        $this->description = '';
        $this->post_edit_id = '';
    }


    public function close()
    {
        $this->resetInputs();
    }

    public function editPost($id)
    {
        $post = Post::find($id);

        $this->post_edit_id = $post->id;
        $this->post_id = $post->post_id;
        $this->title = $post->title;
        $this->status = $post->status;
        $this->description = $post->description;

        $this->dispatchBrowserEvent('show-edit-post-modal');
    }
    
    public function editPostData()
    {
        //on form submit validation
        $this->validate([
            'post_id' => 'required|unique:posts,post_id,'.$this->post_edit_id.'', //Validation with ignoring own data
            'title' => 'required',
            'status' => 'required|in:active,inactive',
            'description' => 'required',
        ]);

        $post = Post::find($this->post_edit_id);

        $post->post_id = $this->post_id;
        $post->title = $this->title;
        $post->status = $this->status;
        $post->description = $this->description;

        $post->save();

        session()->flash('message', 'Post has been updated successfully');

        //For hide modal after add post added successfully
        $this->dispatchBrowserEvent('close-modal');
    }

    //Delete Confirmation
    public function deleteConfirmation($id)
    {
        $this->post_delete_id = $id; //post id

        $this->dispatchBrowserEvent('show-delete-confirmation-modal');
    }


    public function deletePostData()
    {
        Post::destroy($this->post_delete_id);

        session()->flash('message', 'Post has been deleted successfully');

        $this->dispatchBrowserEvent('close-modal');

        $this->post_delete_id = '';
    }

    public function cancel()
    {
        $this->post_delete_id = '';
    }

    public function viewPostDetails($id)
    {
        $post = Post::find($id);

        $this->view_post_id = $post->post_id;
        $this->view_post_title = $post->title;
        $this->view_post_status = $post->status;
        $this->view_post_description = $post->description;

        $this->dispatchBrowserEvent('show-view-post-modal');
    }


    public function closeViewPostModal()
    {
        $this->view_post_id = '';
        $this->view_post_title = '';
        $this->view_post_status = '';
        $this->view_post_description = '';
    }

    public function render()
    {
        //Get all post
        $posts = Post::where('title', 'like', '%'.$this->searchTerm.'%')
        ->orWhere('status', 'like', $this->searchTerm.'%')
        ->orWhere('post_id', 'like', '%'.$this->searchTerm.'%')
        ->orWhere('description', 'like', '%'.$this->searchTerm.'%')
        ->get();

        return view('livewire.posts-component', ['posts'=>$posts])->layout('livewire.layouts.base');
    }
}

Step 12: Setting Blade Component File

From here you can just copy the whole component content for the demonstration purpose and your project and modify it accordingly to your requirement.

resources/views/livewire/posts-component.blade.php

    <div>
        <div class="container mt-5">
            <div class="row mb-5">
                <div class="col-md-12 text-center">
                    <h3><strong>Laravel Livewire CRUD with Bootstrap Modal</strong></h3>
                </div>
            </div>
            <div class="row">
                <div class="col-md-12">
                    <div class="card">
                        <div class="card-header">
                            <h5 style="float: left;"><strong>All Posts</strong></h5>
                            <button class="btn btn-sm btn-primary" style="float: right;" data-toggle="modal" data-target="#addPosttModal">Add New Post</button>
                        </div>
                        <div class="card-body">
                            @if (session()->has('message'))
                                <div class="alert alert-success text-center">{{ session('message') }}</div>
                            @endif
    
    
                            <div class="row mb-3">
                                <div class="col-md-12">
                                    <input type="search" class="form-control w-25" placeholder="search" wire:model="searchTerm" style="float: right;" />
                                </div>
                            </div>
    
    
                            <table class="table table-bordered">
                                <thead>
                                    <tr>
                                        <th>ID</th>
                                        <th>Title</th>
                                        <th>Status</th>
                                        <th>Description</th>
                                        <th style="text-align: center;">Action</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    @if ($posts->count() > 0)
                                        @foreach ($posts as $post)
                                            <tr>
                                                <td>{{ $post->post_id }}</td>
                                                <td>{{ $post->title }}</td>
                                                <td>{{ $post->status }}</td>
                                                <td>{{ $post->description }}</td>
                                                <td style="text-align: center;">
                                                    <button class="btn btn-sm btn-secondary" wire:click="viewPostDetails({{ $post->id }})">View</button>
                                                    <button class="btn btn-sm btn-primary" wire:click="editPost({{ $post->id }})">Edit</button>
                                                    <button class="btn btn-sm btn-danger" wire:click="deleteConfirmation({{ $post->id }})">Delete</button>
                                                </td>
                                            </tr>
                                        @endforeach
                                    @else
                                        <tr>
                                            <td colspan="4" style="text-align: center;"><small>No Post Found</small></td>
                                        </tr>
                                    @endif
                                </tbody>
                            </table>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    
    
        <!-- Modal -->
        <div wire:ignore.self class="modal fade" id="addPosttModal" tabindex="-1" data-backdrop="static" data-keyboard="false" role="dialog" aria-labelledby="modelTitleId" aria-hidden="true">
            <div class="modal-dialog" role="document">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title">Add Post</h5>
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                            <span aria-hidden="true">×</span>
                        </button>
                    </div>
                    <div class="modal-body">
    
    
                        <form wire:submit.prevent="storePost">
                            <div class="form-group row">
                                <label for="post_id" class="col-3">Post ID</label>
                                <div class="col-9">
                                    <input type="number" id="post_id" class="form-control" wire:model="post_id">
                                    @error('post_id')
                                        <span class="text-danger" style="font-size: 11.5px;">{{ $message }}</span>
                                    @enderror
                                </div>
                            </div>
    
    
                            <div class="form-group row">
                                <label for="title" class="col-3">Title</label>
                                <div class="col-9">
                                    <input type="text" id="title" class="form-control" wire:model="title">
                                    @error('title')
                                        <span class="text-danger" style="font-size: 11.5px;">{{ $message }}</span>
                                    @enderror
                                </div>
                            </div>
    
    
                            <div class="form-group row">
                                <label for="status" class="col-3">Status</label>
                                <div class="col-9">
                                    <select name="status" id="status" class="form-control" wire:model="status">
                                        <option selected>Select Status</option>
                                        <option value="active">Active</option>
                                        <option value="inactive">Inactive</option>
                                    </select>
                                    @error('status')
                                        <span class="text-danger" style="font-size: 11.5px;">{{ $message }}</span>
                                    @enderror
                                </div>
                            </div>
    
    
                            <div class="form-group row">
                                <label for="description" class="col-3">Description</label>
                                <div class="col-9">
                                    <textarea type="number" id="description" class="form-control" wire:model="description"></textarea>
                                    @error('description')
                                        <span class="text-danger" style="font-size: 11.5px;">{{ $message }}</span>
                                    @enderror
                                </div>
                            </div>
    
    
                            <div class="form-group row">
                                <label for="" class="col-3"></label>
                                <div class="col-9">
                                    <button type="submit" class="btn btn-sm btn-primary">Save Post</button>
                                </div>
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    
    
        <div wire:ignore.self class="modal fade" id="editPostModal" tabindex="-1" data-backdrop="static" data-keyboard="false" role="dialog" aria-labelledby="modelTitleId" aria-hidden="true">
            <div class="modal-dialog" role="document">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title">Edit Post</h5>
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close" wire:click="close">
                            <span aria-hidden="true">×</span>
                        </button>
                    </div>
                    <div class="modal-body">
    
    
                        <form wire:submit.prevent="editPostData">
                            <div class="form-group row">
                                <label for="post_id" class="col-3">Post ID</label>
                                <div class="col-9">
                                    <input type="number" id="post_id" class="form-control" wire:model="post_id">
                                    @error('post_id')
                                        <span class="text-danger" style="font-size: 11.5px;">{{ $message }}</span>
                                    @enderror
                                </div>
                            </div>
    
                            <div class="form-group row">
                                <label for="title" class="col-3">Title</label>
                                <div class="col-9">
                                    <input type="text" id="title" class="form-control" wire:model="title">
                                    @error('title')
                                        <span class="text-danger" style="font-size: 11.5px;">{{ $message }}</span>
                                    @enderror
                                </div>
                            </div>
    
    
                            <div class="form-group row">
                                <label for="status" class="col-3">Status</label>
                                <div class="col-9">
                                    <select name="status" id="status" class="form-control" wire:model="status">
                                        <option selected>Select Status</option>
                                        <option value="active">Active</option>
                                        <option value="inactive">Inactive</option>
                                    </select>
                                    @error('status')
                                        <span class="text-danger" style="font-size: 11.5px;">{{ $message }}</span>
                                    @enderror
                                </div>
                            </div>
    
    
                            <div class="form-group row">
                                <label for="description" class="col-3">Description</label>
                                <div class="col-9">
                                    <textarea type="number" id="description" class="form-control" wire:model="description"></textarea>
                                    @error('description')
                                        <span class="text-danger" style="font-size: 11.5px;">{{ $message }}</span>
                                    @enderror
                                </div>
                            </div>
    
                            <div class="form-group row">
                                <label for="" class="col-3"></label>
                                <div class="col-9">
                                    <button type="submit" class="btn btn-sm btn-primary">Edit Post</button>
                                </div>
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    
    
        <div wire:ignore.self class="modal fade" id="deletePostModal" tabindex="-1" data-backdrop="static" data-keyboard="false" role="dialog" aria-labelledby="modelTitleId" aria-hidden="true">
            <div class="modal-dialog" role="document">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title">Delete Confirmation</h5>
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                            <span aria-hidden="true">×</span>
                        </button>
                    </div>
                    <div class="modal-body pt-4 pb-4">
                        <h6>Are you sure? You want to delete this post!</h6>
                    </div>
                    <div class="modal-footer">
                        <button class="btn btn-sm btn-primary" wire:click="cancel()" data-dismiss="modal" aria-label="Close">Cancel</button>
                        <button class="btn btn-sm btn-danger" wire:click="deletePostData()">Yes! Delete</button>
                    </div>
                </div>
            </div>
        </div>
    
    
        <div wire:ignore.self class="modal fade" id="viewPostModal" tabindex="-1" data-backdrop="static" data-keyboard="false" role="dialog" aria-labelledby="modelTitleId" aria-hidden="true">
            <div class="modal-dialog" role="document">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title">Post In Details</h5>
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close" wire:click="closeViewPostModal">
                            <span aria-hidden="true">×</span>
                        </button>
                    </div>
                    <div class="modal-body">
                        <table class="table table-bordered">
                            <tbody>
                                <tr>
                                    <th>ID: </th>
                                    <td>{{ $view_post_id }}</td>
                                </tr>
    
                                <tr>
                                    <th>Title: </th>
                                    <td>{{ $view_post_title }}</td>
                                </tr>
    
                                <tr>
                                    <th>Status: </th>
                                    <td>{{ $view_post_status }}</td>
                                </tr>
    
                                <tr>
                                    <th>Description: </th>
                                    <td>{{ $view_post_description }}</td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
    </div>
    
    
    @push('scripts')
        <script>
            window.addEventListener('close-modal', event =>{
                $('#addPosttModal').modal('hide');
                $('#editPostModal').modal('hide');
                $('#deletePostModal').modal('hide');
            });
    
    
            window.addEventListener('show-edit-post-modal', event => {
                $('#editPostModal').modal('show');
            });
    
    
            window.addEventListener('show-delete-confirmation-modal', event => {
                $('#deletePostModal').modal('show');
            });
    
    
            window.addEventListener('show-view-post-modal', event => {
                $('#viewPostModal').modal('show');
            });
        </script>
    @endpush

Laravel 8 9 Livewire Image Upload Tutorial With Example

Step 13: Run Server

Now, Time to run our project for testing, Goto your terminal where you locate your project and run the below-given command. This command will start your development server.

php artisan serve

Run our routes which we define in your routes file.

http://127.0.0.1:8000/post

OUTPUT :

Add Post

This is to add this model open when you will click on the App Post button.

image

Post List

This is a post listing once you add your post this list will fetch your listing data from the database.

image

Post View

You can also read/view your post by clicking on the view button from the listing action.

image

Post Edit/Update

You can also edit your post once you created

image

Post Delete

You can also delete this post, This will also ask for confirmation from you.

image

We always thanks to you for reading our blogs.


dharmesh-image

Dharmesh Chauhan

(Swapinfoway Founder)

Hello Sir, We are brothers origin from Gujarat India, Fullstack developers working together since 2016. We have lots of skills in web development in different technologies here I mention PHP, Laravel, Javascript, Vuejs, Ajax, API, Payment Gateway Integration, Database, HTML5, CSS3, and Server Administration. So you need our service Please Contact Us

haresh-image

Haresh Chauhan

(Co-Founder)


We Are Also Recommending You :