Laravel Livewire 3 CRUD Tutorial: Build a Dynamic App with Livewire

Laravel Livewire 3 CRUD Tutorial: Build a Dynamic App with Livewire

Livewire is a powerful tool for building dynamic Laravel applications without writing extensive JavaScript. This guide will walk you through implementing CRUD (Create, Read, Update, Delete) operations in Laravel using Livewire.

Prerequisites

  • Laravel installed (e.g., version 10 or 11 or 12).
  • Livewire installed.
  • A MySQL database configured.

Run the following commands to set up a fresh Laravel project and install Livewire:

composer create-project laravel/laravel livewire-crud
cd livewire-crud
composer require livewire/livewire

Step 1: Set Up the Database

  1. Configure the .env file with database credentials:
  2. DB_CONNECTION=mysql
    DB_HOST=127.0.0.1
    DB_PORT=3306
    DB_DATABASE=your_database
    DB_USERNAME=your_username
    DB_PASSWORD=your_password
    
  3. Create a Model and Migration for "Posts":
  4. php artisan make:model Post -m
    
  5. Edit the Migration File (database/migrations/xxxx_create_posts_table.php):
  6. public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('body');
            $table->timestamps();
        });
    }
    
  7. Run the Migration:
  8. php artisan migrate
    
  9. Update the Post Model (app/Models/Post.php):
  10. class Post extends Model
    {
        protected $fillable = ['title', 'body'];
    }
    

Step 2: Create a Livewire Component

  1. Generate a Livewire Component:
  2. php artisan make:livewire Posts
    
  3. Edit the Component (app/Livewire/Posts.php):
<?php

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

class Posts extends Component
{
    public $posts, $title, $body, $postId;
    public $isEditing = false;

    protected $rules = [
        'title' => 'required|min:3',
        'body' => 'required|min:5',
    ];

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

    public function store()
    {
        $this->validate();
        Post::create([
            'title' => $this->title,
            'body' => $this->body,
        ]);
        $this->resetInput();
    }

    public function edit($id)
    {
        $post = Post::findOrFail($id);
        $this->postId = $id;
        $this->title = $post->title;
        $this->body = $post->body;
        $this->isEditing = true;
    }

    public function update()
    {
        $this->validate();
        $post = Post::find($this->postId);
        $post->update([
            'title' => $this->title,
            'body' => $this->body,
        ]);
        $this->resetInput();
        $this->isEditing = false;
    }

    public function delete($id)
    {
        Post::find($id)->delete();
    }

    private function resetInput()
    {
        $this->title = '';
        $this->body = '';
        $this->postId = null;
    }
}

Step 3: Create the View

Edit resources/views/livewire/posts.blade.php:

<div class="container mt-5">
    <div class="card shadow-lg">
        <div class="card-header bg-primary text-white text-center">
            <h2>Posts CRUD with Livewire</h2>
        </div>
        <div class="card-body">
            <!-- Form for Create/Update -->
            <form wire:submit.prevent="{{ $isEditing ? 'update' : 'store' }}">
                <div class="mb-3">
                    <label class="form-label">Title</label>
                    <input type="text" class="form-control" wire:model="title" placeholder="Enter title">
                    @error('title') <div class="text-danger">{{ $message }}</div> @enderror
                </div>
                <div class="mb-3">
                    <label class="form-label">Body</label>
                    <textarea class="form-control" wire:model="body" placeholder="Enter body"></textarea>
                    @error('body') <div class="text-danger">{{ $message }}</div> @enderror
                </div>
                <button type="submit" class="btn btn-success">{{ $isEditing ? 'Update' : 'Add' }} Post</button>
                @if($isEditing)
                    <button type="button" class="btn btn-secondary" wire:click="$set('isEditing', false)">Cancel</button>
                @endif
            </form>
        </div>
    </div>

    <!-- Posts List -->
    <div class="card mt-4 shadow-lg">
        <div class="card-body">
            <table class="table table-bordered table-striped">
                <thead class="table-dark">
                    <tr>
                        <th>Title</th>
                        <th>Body</th>
                        <th>Actions</th>
                    </tr>
                </thead>
                <tbody>
                    @forelse ($posts as $post)
                        <tr>
                            <td>{{ $post->title }}</td>
                            <td>{{ $post->body }}</td>
                            <td>
                                <button class="btn btn-warning btn-sm" wire:click="edit({{ $post->id }})">Edit</button>
                                <button class="btn btn-danger btn-sm" wire:click="delete({{ $post->id }})">Delete</button>
                            </td>
                        </tr>
                    @empty
                        <tr>
                            <td colspan="3" class="text-center">No posts found.</td>
                        </tr>
                    @endforelse
                </tbody>
            </table>
        </div>
    </div>
</div>

Step 4: Set Up the Route and Layout

By default, Laravel uses the / route. You can define it in your web.php file as follows:

Route::get('/', function () {
    return view('welcome');
});

This route returns the welcome view when users visit the homepage.

Edit the Welcome Blade File (resources/views/welcome.blade.php)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Laravel Livewire CRUD</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
    @livewireStyles
</head>
<body class="bg-light">
  <livewire:posts />
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
    @livewireScripts
</body>
</html>

Step 5: Run the Application

Start the Laravel development server:

php artisan serve

Visit http://127.0.0.1:8000/posts in your browser.

Conclusion

This CRUD app demonstrates how Livewire simplifies dynamic UI updates in Laravel. You can enhance it with styling frameworks like Bootstrap or Tailwind CSS. Let me know if you need further improvements!

Laravel Livewire 3 CRUD


0 Comments