Laravel 9 Livewire CRUD Application Tutorial Example

Throughtout this Laravel 9 Livewire CRUD example tutorial, we will learn step by step on how to buide CRUD application operation with bootstrap UI and search funcationality in the Laravel application using Livewire package.

This tutorial will guide you from scratch about step by step how to implement CRUD operation using the help of the livewire package in the laravel application. You can use livewire CRUD Example in laravel 6, laravel 7, laravel 8 and laravel 9 apps.

Laravel Livewire CRUD Operation Example

This quick and simple tutorial offers you a facile example of a CRUD operation using bootstrap UI design in laravel app with livewire library.

Use to the following steps to implement pagination example with search funcationality in laravel 9 app with livewire:

  • Step 1: Install Laravel App
  • Step 2: Connect App to Database
  • Step 3: Create Model & Migration
  • Step 4: Install Livewire Package
  • Step 5: Create Post Component
  • Step 6: Make Routes
  • Step 7: Create Blade file and Render
  • Step 8: Run Development Server

Install Laravel App

First run the following command in terminal to install laravel fresh app for laravel livewire pagination with search example app.

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

Go into the app:

cd laravel-livewire

Configure Database Credentials

Open the .env file and add your database credentials such as database name, username equally important password:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=db name
DB_USERNAME=db user name
DB_PASSWORD=db password

Create Model & Migration

Now generate model and migration file just adding the below command in your terminal which is generate a model file and migration which will show your database table after running the migration command.

php artisan make:model Post -m

Now you can see in your database migration directory created a new file same as below, here you need to add you database columns.

database\migrations\2020_09_13_071913_create_projects_table.php

<?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('title')->nullable();
            $table->longText('description')->nullable();
            $table->timestamps();
        });
    }

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

After adding the columns now run the below command which is generate table in your database.

php artisan migrate

Add Fillable Property: In your app/models inside generated a new file Post.php file where you need to add fillable properties.

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 = [
      'title', 'description'
    ];
}

Install Livewire Package

In this step, we need to install livewire package to laravel project using the following command:

composer require livewire/livewire

Create Post Component for Laravel Livewire CRUD Operation

Go to console run the artisan command to create the livewire components for laravel livewire CRUD operation:

php artisan make:livewire posts

The above command generated two files on the following path:

app/Http/Livewire/Post.php
resources/views/livewire/posts.blade.php

Go ahead and place the below code in the app/Http/Livewire/Post.php file:

<?php
  
namespace App\Http\Livewire;
  
use Livewire\Component;
use App\Post;
  
class Posts extends Component
{
    public $posts, $title, $description, $post_id;
    public $updateMode = false;
   
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    public function render()
    {
        $this->posts = Post::all();
        return view('livewire.posts');
    }
  
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    private function resetInputFields(){
        $this->title = '';
        $this->description = '';
    }
   
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    public function store()
    {
        $validatedDate = $this->validate([
            'title' => 'required',
            'description' => 'required',
        ]);
  
        Post::create($validatedDate);
  
        session()->flash('message', 'Post Created Successfully.');
  
        $this->resetInputFields();
    }
  
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    public function edit($id)
    {
        $post = Post::findOrFail($id);
        $this->post_id = $id;
        $this->title = $post->title;
        $this->description = $post->description;
  
        $this->updateMode = true;
    }
  
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    public function cancel()
    {
        $this->updateMode = false;
        $this->resetInputFields();
    }
  
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    public function update()
    {
        $validatedDate = $this->validate([
            'title' => 'required',
            'description' => 'required',
        ]);
  
        $post = Post::find($this->post_id);
        $post->update([
            'title' => $this->title,
            'description' => $this->description,
        ]);
  
        $this->updateMode = false;
  
        session()->flash('message', 'Post Updated Successfully.');
        $this->resetInputFields();
    }
   
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    public function delete($id)
    {
        Post::find($id)->delete();
        session()->flash('message', 'Post Deleted Successfully.');
    }
}

Next, open posts.blade.php, which is located inside resources/views/livewire/ directory and add the following code into it:

<div>
    @if($updateMode)
        @include('livewire.update')
    @else
        @include('livewire.create')
    @endif
    <table class="table table-bordered mt-5">
        <thead>
            <tr>
                <th>No.</th>
                <th>Title</th>
                <th>Description</th>
                <th>Action</th>
            </tr>
        </thead>
        <tbody>
            @foreach($posts as $value)
            <tr>
                <td>{{ $value->id }}</td>
                <td>{{ $value->title }}</td>
                <td>{{ $value->description }}</td>
                <td>
                <button wire:click="edit({{ $value->id }})" class="btn btn-primary btn-sm">Edit</button>
                <button wire:click="delete({{ $value->id }})" class="btn btn-danger btn-sm">Delete</button>
                </td>
            </tr>
            @endforeach
        </tbody>
    </table>
</div>

Make Routes

Open routes/web.php file and define the route to access the laravel livewire post crud view file:

use App\Http\Livewire\Posts;
Route::get('posts', Posts::class);

Create Blade Views & Render

Go to resources/views/livewire directory and create the following blade views:

  • Create.blade.php
  • Update.blade.php

Then add the following code into this files:

First open the Create.blade.php file and put the below code on it:

<form>
    <div class="form-group">
        <label for="exampleFormControlInput1">Title</label>
        <input type="text" class="form-control" id="exampleFormControlInput1" placeholder="Enter Title" wire:model="title">
        @error('title') <span class="text-danger">{{ $message }}</span>@enderror
    </div>
    <div class="form-group">
        <label for="exampleFormControlInput2">Description</label>
        <input type="text" class="form-control" id="exampleFormControlInput2" wire:model="description" placeholder="Enter Description">
        @error('description') <span class="text-danger">{{ $message }}</span>@enderror
    </div>
    <button wire:click.prevent="store()" class="btn btn-success">Save</button>
</form>

Next, open Update.blade.php file and sequencelly update the following code inside;

<form>
    <div class="form-group">
        <input type="hidden" wire:model="post_id">
        <label for="exampleFormControlInput1">Title</label>
        <input type="text" class="form-control" wire:model="title" id="exampleFormControlInput1" placeholder="Enter Title">
        @error('title') <span class="text-danger">{{ $message }}</span>@enderror
    </div>
    <div class="form-group">
        <label for="exampleFormControlInput2">Description</label>
        <input type="text" class="form-control" wire:model="description" id="exampleFormControlInput2" placeholder="Enter Description">
        @error('description') <span class="text-danger">{{ $message }}</span>@enderror
    </div>
    <button wire:click.prevent="update()" class="btn btn-dark">Update</button>
    <button wire:click.prevent="cancel()" class="btn btn-danger">Cancel</button>
</form>

In last open the welcome.blade.php file and update the below code on it;

<!DOCTYPE html>
<html>
<head>
    <title>Laravel Livewire CRUD Example- codingdriver.com</title>
    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet">
    @livewireStyles
</head>
<body>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header">
                        <h2>Laravel Livewire CRUD Example - codingdriver.com</h2>
                    </div>
                    <div class="card-body">
                        @if (session()->has('message'))
                            <div class="alert alert-success">
                                {{ session('message') }}
                            </div>
                        @endif
                        @livewire('posts')
                    </div>
                </div>
            </div>
        </div>
    </div>
    @livewireScripts
</body>
</html>

Start Development Server

Execute the following command on the command prompt to start the development server for laravel 9 livewire crud app:

php artisan serve

Last, open browser and fire the following url into browser:

http://127.0.0.1:8000/posts

The Laravel Livewire CRUD operation Example Tutorial is over; in this tutorial, we learned the easiest way to buid CRUD operation example in laravel application using the livewire library.