Laravel Livewire CRUD example from the scratch

Livewire is full-stack Laravel library that allows to build modern, reactive, dynamic interfaces using Laravel Blade as your templating language. If you want to build dynamic interfaces, then Livewire is perfect framework library.

In this tutorial article, we will create CRUD functionality in Laravel using Livewire library step by step from the scratch. So lets jump in the coding.

Note: You need to have installed Composer application. Composer installs Laravel application and manages all PHP packages.

Step 1: Create Laravel application

First of all, we will create new fresh Laravel application. So Open the Terminal and run the below composer command. This will create new Laravel application with the same name.

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

After that change working directory to application

cd livewire

Step 2: Install Livewire

Now we will need to install Livewire library. Run the below composer command.

composer require livewire/livewire

Step 3: Laravel environment setup

After we have successfully installed all necessary packages, we will need to setup database. Open .env file from root directory of application and change database variables according to your system.

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

After that run migrate command to create users table.

php artisan migrate

Step 4: Create route

We need route to load view where we will create CRUD part. Open routes/web.php file and add a new route.

<?php

Route::view('users', 'livewire.index');

Step 5: Create Component

We will create CRUD for users, so we will need to create User component. Run the below artisan command.

php artisan make:livewire users

The command will generate below two files.

CLASS: app/Http/Livewire/Users.php
VIEW:  resources/views/livewire/users.blade.php

First open app/Http/Livewire/Users.php file and add the methods in it.

<?php

namespace App\Http\Livewire;

use App\Models\User;
use Livewire\Component;

class Users extends Component
{
    public $users, $name, $email, $user_id;
    public $is_update = false;

    public function render()
    {
        $this->users = User::all();

        return view('livewire.users');
    }

    private function clearForm()
    {
        $this->name = '';
        $this->email = '';
    }

    public function store()
    {
        $validated = $this->validate([
            'name' => 'required',
            'email' => 'required|email',
        ]);

        User::create($validated);

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

        $this->clearForm();
    }

    public function edit($id)
    {
        $user = User::where('id', $id)->first();
        
        $this->is_update = true;
        $this->user_id = $id;
        $this->name = $user->name;
        $this->email = $user->email;
    }

    public function cancel()
    {
        $this->is_update = false;
        $this->clearForm();
    }

    public function update()
    {
        $validated = $this->validate([
            'name' => 'required',
            'email' => 'required|email',
        ]);

        $user = User::find($this->user_id);
        
        $user->update([
            'name' => $this->name,
            'email' => $this->email,
        ]);

        $this->is_update = false;
        $this->clearForm();
        
        session()->flash('message', 'Users Updated Successfully.');
    }

    public function delete($id)
    {
        User::where('id', $id)->delete();

        session()->flash('message', 'Users Deleted Successfully.');
    }
}

Step 6: Create blade views

In this step, we will create below views file to manage users.

/resources
    /views
        /livewire
            /index.blade.php
            /users.blade.php
            /create.blade.php
            /update.blade.php


index.blade.php is master file for layout. All the other views are loaded on it.

<!DOCTYPE html>
<html>
<head>
    <title>Users</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
    @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>Users</h2>
                    </div>
                    <div class="card-body">
                        @if (session()->has('message'))
                            <div class="alert alert-success">
                                {{ session('message') }}
                            </div>
                        @endif
                        @livewire('users')
                    </div>
                </div>
            </div>
        </div>
    </div>
    @livewireScripts
</body>
</html>

users.blade.php file is already created with component. So just add the codes in it.

<div>
    @if($is_update)
        @include('livewire.update')
    @else
        @include('livewire.create')
    @endif
    <table class="table table-bordered mt-5">
        <thead>
            <tr>
                <th>#</th>
                <th>Name</th>
                <th>Email</th>
                <th>Action</th>
            </tr>
        </thead>
        <tbody>
            @foreach($users as $value)
                <tr>
                    <td>{{ $value->id }}</td>
                    <td>{{ $value->name }}</td>
                    <td>{{ $value->email }}</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>

create.blade.php view will add create form.

<form>
    <div class="form-group">
        <label for="username">Name</label>
        <input type="text" class="form-control" id="username" placeholder="Enter Name" wire:model="name">
        @error('name') <span class="text-danger">{{ $message }}</span>@enderror
    </div>
    <div class="form-group">
        <label for="usermail">Email address</label>
        <input type="email" class="form-control" id="usermail" wire:model="email" placeholder="Enter Email">
        @error('email') <span class="text-danger">{{ $message }}</span>@enderror
    </div>
    <button wire:click.prevent="store()" class="btn btn-success">Save</button>
</form>

update.blade.php view is required to update user details.

<form>
    <div class="form-group">
        <input type="hidden" wire:model="user_id">
        <label for="username">Name</label>
        <input type="text" class="form-control" wire:model="name" id="username" placeholder="Enter Name">
        @error('name') <span class="text-danger">{{ $message }}</span>@enderror
    </div>
    <div class="form-group">
        <label for="usermail">Email address</label>
        <input type="email" class="form-control" wire:model="email" id="usermail" placeholder="Enter Email">
        @error('email') <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>

Now our coding part is done, we will need to run Laravel application and test it. Run the artisan command to start application server.

php artisan serve

And open below URL on your browser:

http://localhost:8000/users

Conclusion

So, in this tutorial, you have learn to create CRUD operation in Livewire. This way you can create more component and use it in your project. I hope you liked this article and help in your work. Thank you for giving time in reading article.