Manage Your VPS Server without Touching Command Line

Register now and Redeem Credits

Redeem Code: TECHVBLOGS

Laravel Livewire Crud Tutorial

  Suresh Ramani   Laravel   4 months ago
Laravel Livewire Crud Tutorial - TechvBlogs

What is Livewire?

Livewire is a full-stack framework for Laravel that makes building dynamic interfaces simple, without leaving the comfort of Laravel. Livewire relies solely on AJAX requests to do all its server communications. Livewire completely sends Ajax requests to do all its server-side communication without writing any line of Ajax script.

In this blog, we have described a step-by-step guide for Creating CRUD (Create, Read, Update, Delete) Application in the Laravel 8 framework by using the Livewire package.

Table Of Contents
  1. Create Laravel Application
  2. Configure Database Details
  3. Install Livewire Package
  4. Create Model and Migration
  5. Create Livewire Component and View
  6. Define Routes
  7. Run Project

Step 1: Create Laravel Application

First, open Terminal and run the following command to create a fresh laravel project:

composer create-project --prefer-dist laravel/laravel larawire-crud-app

or, if you have installed the Laravel Installer as a global composer dependency:

laravel new larawire-crud-app

Step 2: Configure Database Details

After, Installation Go to the project root directory, open .env file, and set database detail as follow:

DB_CONNECTION=mysql 
DB_HOST=127.0.0.1 
DB_PORT=3306 
DB_DATABASE=<DATABASE NAME>
DB_USERNAME=<DATABASE USERNAME>
DB_PASSWORD=<DATABASE PASSWORD>

Step 3: Install Livewire Package:

composer require livewire/livewire

Step 4: Create Model and Migration:

php artisan make:model Category -m

-m this argument will create Migration in Single Command.

Now, Open migration file of category from database/migration and replace code in up() function:

public function up()
{
    Schema::create('categories', function (Blueprint $table) {
        $table->id();
        $table->string('name')->nullable();
        $table->text('description')->nullable();
        $table->timestamps();
    });
}

Migrate the database using the following command:

php artisan migrate

Now, Open Category.php model from app/Models and update code into Category.php Model:

namespace App\Models;

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

class Category extends Model
{
    use HasFactory;

    protected $fillable = [
        'name', 'description'
    ];

    public $timestamps = true;
}

Step 5: Create Livewire Component and View

Run the below command to create a livewire view and component.

php artisan make:livewire category

After running this command you will find two files in the following path app/Http/Livewire/Contact.php and resources/views/livewire/contact.blade.php

Now, open app\Http\Livewire\Category.php and update the following code into that file:

namespace App\Http\Livewire;

use Livewire\Component;
use App\Models\Category as Categories;

class Category extends Component
{
    public $categories, $name, $description, $category_id;
    public $updateCategory = false;

    protected $listeners = [
        'deleteCategory'=>'destroy'
    ];

    // Validation Rules
    protected $rules = [
        'name'=>'required',
        'description'=>'required'
    ];

    public function render()
    {
        $this->categories = Categories::select('id','name','description')->get();
        return view('livewire.category');
    }

    public function resetFields(){
        $this->name = '';
        $this->description = '';
    }

    public function store(){

        // Validate Form Request
        $this->validate();

        try{
            // Create Category
            Categories::create([
                'name'=>$this->name,
                'description'=>$this->description
            ]);
    
            // Set Flash Message
            session()->flash('success','Category Created Successfully!!');

            // Reset Form Fields After Creating Category
            $this->resetFields();
        }catch(\Exception $e){
            // Set Flash Message
            session()->flash('error','Something goes wrong while creating category!!');

            // Reset Form Fields After Creating Category
            $this->resetFields();
        }
    }

    public function edit($id){
        $category = Categories::findOrFail($id);
        $this->name = $category->name;
        $this->description = $category->description;
        $this->category_id = $category->id;
        $this->updateCategory = true;
    }

    public function cancel()
    {
        $this->updateCategory = false;
        $this->resetFields();
    }

    public function update(){

        // Validate request
        $this->validate();

        try{

            // Update category
            Categories::find($this->category_id)->fill([
                'name'=>$this->name,
                'description'=>$this->description
            ])->save();

            session()->flash('success','Category Updated Successfully!!');
    
            $this->cancel();
        }catch(\Exception $e){
            session()->flash('error','Something goes wrong while updating category!!');
            $this->cancel();
        }
    }

    public function destroy($id){
        try{
            Categories::find($id)->delete();
            session()->flash('success',"Category Deleted Successfully!!");
        }catch(\Exception $e){
            session()->flash('error',"Something goes wrong while deleting category!!");
        }
    }
}

Now, Create resources/views/home.blade.php and update the following code into that file:

<!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>Livewire Crud Example - TechvBlogs</title>

    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
    @livewireStyles
</head>
<body>
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
        <div class="container-fluid">
            <a class="navbar-brand" href="/">Livewire Crud Example - TechvBlogs</a>
        </div>
    </nav>

    <div class="container">
        <div class="row justify-content-center mt-3">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header text-center">
                        <h2>Livewire Crud Example - TechvBlogs</h2>
                        <a href="https://techvblogs.com?ref=LivewireCrudApp" target="_blank">Visit Site</a>
                    </div>
                </div>
            </div>
        </div>
        <div class="row justify-content-center mt-3">
            @livewire('category')
        </div>
    </div>
    
    @livewireScripts
</body>
</html>

Next, Open resources/views/livewire/category.blade.php and update the following code into that file:

<div>
    <div class="col-md-8 mb-2">
        <div class="card">
            <div class="card-body">
                @if(session()->has('success'))
                    <div class="alert alert-success" role="alert">
                        {{ session()->get('success') }}
                    </div>
                @endif

                @if(session()->has('error'))
                    <div class="alert alert-danger" role="alert">
                        {{ session()->get('error') }}
                    </div>
                @endif

                @if($updateCategory)
                    @include('livewire.update')
                @else
                    @include('livewire.create')
                @endif
            </div>
        </div>
    </div>

    <div class="col-md-8">
        <div class="card">
            <div class="card-body">
                <div class="table-responsive">
                    <table class="table">
                        <thead>
                            <tr>
                                <th>Name</th>
                                <th>Description</th>
                                <th>Action</th>
                            </tr>
                        </thead>
                        <tbody>
                            @if (count($categories) > 0)
                                @foreach ($categories as $category)
                                    <tr>
                                        <td>
                                            {{$category->name}}
                                        </td>
                                        <td>
                                            {{$category->description}}
                                        </td>
                                        <td>
                                            <button wire:click="edit({{$category->id}})" class="btn btn-primary btn-sm">Edit</button>
                                            <button onclick="deleteCategory({{$category->id}})" class="btn btn-danger btn-sm">Delete</button>
                                        </td>
                                    </tr>
                                @endforeach
                            @else
                                <tr>
                                    <td colspan="3" align="center">
                                        No Categories Found.
                                    </td>
                                </tr>
                            @endif
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>

    <script>
        function deleteCategory(id){
            if(confirm("Are you sure to delete this record?"))
                window.livewire.emit('deleteCategory',id);
        }
    </script>
</div>

Now, Create resources/views/livewire/create.blade.php and add the following code into that file:

<form>
    <div class="form-group mb-3">
        <label for="categoryName">Name:</label>
        <input type="text" class="form-control @error('name') is-invalid @enderror" id="categoryName" placeholder="Enter Name" wire:model="name">
        @error('name') <span class="text-danger">{{ $message }}</span>@enderror
    </div>
    <div class="form-group mb-3">
        <label for="categoryDescription">Description:</label>
        <textarea class="form-control @error('description') is-invalid @enderror" id="categoryDescription" wire:model="description" placeholder="Enter Description"></textarea>
        @error('description') <span class="text-danger">{{ $message }}</span>@enderror
    </div>
    <div class="d-grid gap-2">
        <button wire:click.prevent="store()" class="btn btn-success btn-block">Save</button>
    </div>
</form>

Next, Create resources/views/livewire/update.blade.php and update the following code into that file:

<form>
    <input type="hidden" wire:model="category_id">
    <div class="form-group mb-3">
        <label for="categoryName">Name:</label>
        <input type="text" class="form-control @error('name') is-invalid @enderror" id="categoryName" placeholder="Enter Name" wire:model="name">
        @error('name') <span class="text-danger">{{ $message }}</span>@enderror
    </div>
    <div class="form-group mb-3">
        <label for="categoryDescription">Description:</label>
        <textarea class="form-control @error('description') is-invalid @enderror" id="categoryDescription" wire:model="description" placeholder="Enter Description"></textarea>
        @error('description') <span class="text-danger">{{ $message }}</span>@enderror
    </div>
    <div class="d-grid gap-2">
        <button wire:click.prevent="update()" class="btn btn-success btn-block">Save</button>
        <button wire:click.prevent="cancel()" class="btn btn-danger">Cancel</button>
    </div>
</form>

Step 6: Define Routes

Open routes/web.php and update the following code into that file:

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

Step 7: Run Project

Now all are set to go, open a terminal and run the following command into your terminal.

php artisan serve

Now you can open bellow URL on your browser:

http://localhost:8000

It'd be a good idea to follow along with the simple demo app that can be found in this GitHub repo.

Read Also: Build Crud App with Laravel and Vue.js

If you have any queries or doubts about this topic please feel free to contact us. We will try to reach you.


Suresh Ramani - Author - TechvBlogs
Suresh Ramani
Laravel & Vue.js Developer
Advertise Here