Laravel 11 Livewire CRUD Tutorial

Throughout this Laravel 11 Livewire CRUD Tutorial, we have guide you how to create a CRUD (Create, Read, Update, Delete) application using the Laravel 10 framework with the assistance of the Livewire package.

To implement CRUD operations with a Laravel 11 application using Livewire, follow these steps to set up and manage your database records:

Step 1: Create Migration and Model

Begin by creating a model and a migration file for CRUD operations:

php artisan make:model Post -m

Next, modify the migration file located at database/migrations/posts.php with the following schema:

Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('body');
$table->timestamps();
});

Then, add the fillable properties to the Post model at app/Models/Post.php:

protected $fillable = [
'title', 'body'
];

Step 2: Set Up Livewire

Install the Livewire package by running:

composer require livewire/livewire

Step 3: Create CRUD Livewire Component

Generate a Livewire component for handling CRUD operations:

php artisan make:livewire posts

Step 4: Implement CRUD Functionality in Component File

Update the Posts Livewire component located at app/Http/Livewire/Posts.php with the following code:

namespace App\Http\Livewire;

use Livewire\Component;
use App\Models\Post;

class Posts extends Component
{
public $posts, $title, $body, $post_id;
public $updateMode = false;

public function render()
{
$this->posts = Post::all();
return view('livewire.posts');
}

private function resetInputFields(){
$this->title = '';
$this->body = '';
}

public function store()
{
$validatedData = $this->validate([
'title' => 'required',
'body' => 'required',
]);

Post::create($validatedData);

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

$this->resetInputFields();
}

public function edit($id)
{
$post = Post::findOrFail($id);
$this->post_id = $id;
$this->title = $post->title;
$this->body = $post->body;

$this->updateMode = true;
}

public function cancel()
{
$this->updateMode = false;
$this->resetInputFields();
}

public function update()
{
$validatedData = $this->validate([
'title' => 'required',
'body' => 'required',
]);

$post = Post::find($this->post_id);
$post->update([
'title' => $this->title,
'body' => $this->body,
]);

$this->updateMode = false;

session()->flash('message', 'Post Updated Successfully.');
$this->resetInputFields();
}

public function delete($id)
{
Post::find($id)->delete();
session()->flash('message', 'Post Deleted Successfully.');
}
}

Step 5: Create CRUD Views

Create or update the views for CRUD operations.

1. resources/views/livewire/posts.blade.php

<div>
@if (session()->has('message'))
<div class="alert alert-success">
{{ session('message') }}
</div>
@endif

@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>Body</th>
<th width="150px">Action</th>
</tr>
</thead>
<tbody>
@foreach($posts as $post)
<tr>
<td>{{ $post->id }}</td>
<td>{{ $post->title }}</td>
<td>{{ $post->body }}</td>
<td>
<button wire:click="edit({{ $post->id }})" class="btn btn-primary btn-sm">Edit</button>
<button wire:click="delete({{ $post->id }})" class="btn btn-danger btn-sm">Delete</button>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>

2. Create create.blade.php in resources/views/livewire/

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

3. Create update.blade.php in resources/views/livewire/

<form>
<input type="hidden" wire:model="post_id">
<div class="form-group">
<label for="title">Title:</label>
<input type="text" class="form-control" id="title" placeholder="Enter Title" wire:model="title">
@error('title') <span class="text-danger">{{ $message }}</span>@enderror
</div>
<div class="form-group">
<label for="body">Body:</label>
<textarea class="form-control" id="body" wire:model="body" placeholder="Enter Body"></textarea>
@error('body') <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>

Step 6: Integrate Livewire Component into Main View

Modify the resources/views/welcome.blade.php to include the Livewire component:

<!DOCTYPE html>
<html>
<head>
<title>Laravel 11 Livewire CRUD Example</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/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 11 Livewire CRUD Example</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>

Step 7: Run and Test the Application

Start the Laravel server:

php artisan serve

Navigate to http://localhost:8000/ in your browser to see and interact with your CRUD application.