Laravel 10 Livewire CRUD Application Example

Laravel Livewire is a popular framework for building dynamic web applications in Laravel. It combines the best of server-side and client-side development by allowing you to write interactive UI components on the server-side using PHP and have them update the UI on the client-side without requiring a page refresh.

Step 1: Install Laravel App

composer create-project laravel/laravel livewire

Step 2: Create Migration and Model 

we need create database migration for "posts" table and also we will create model for files table.

php artisan make:migration create_posts_table

Migration:

<?php
  
    use Illuminate\Database\Migrations\Migration;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Support\Facades\Schema;
      
    return new class extends Migration
    {
        /**
         * Run the migrations.
         *
         * @return void
         */
        public function up(): void
        {
            Schema::create('posts', function (Blueprint $table) {
                $table->id();
                $table->string('title');
                $table->text('body');
                $table->timestamps();
            });
        }
      
        /**
         * Reverse the migrations.
         *
         * @return void
         */
        public function down(): void
        {
            Schema::dropIfExists('posts');
        }
    };
php artisan migrate

Now, we will create "Post" model,

php artisan make:model Post

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;
      
        /**
         * The attributes that are mass assignable.
         *
         * @var array
         */
        protected $fillable = [
            'title', 'body'
        ];
    }

Step 3: Install Livewire

Next Step we will simply install livewire  

composer require livewire/livewire

Step 4: Create Post Component

 Now, we will create livewire component using their command 

php artisan make:livewire posts

Now ,created fies for both path:

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

Step 5: Update Component File

render(), resetInputFields(), store(), edit(), cancel(), update() and delete() These all are methods which update in following file,

app/Http/Livewire/Posts.php 

<?php
  
    namespace App\Http\Livewire;
      
    use Livewire\Component;
    use App\Models\Post;
      
    class Posts extends Component
    {
        public $posts, $title, $body, $post_id;
        public $updateMode = false;
       
        /**
         * The attributes that are mass assignable.
         *
         * @var array
         */
        public function render()
        {
            $this->posts = Post::latest()->get();
            return view('livewire.posts');
        }
      
        /**
         * The attributes that are mass assignable.
         *
         * @var array
         */
        private function resetInputFields(){
            $this->title = '';
            $this->body = '';
        }
       
        /**
         * The attributes that are mass assignable.
         *
         * @var array
         */
        public function store()
        {
            $validatedDate = $this->validate([
                'title' => 'required',
                'body' => '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->body = $post->body;
      
            $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',
                '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();
        }
       
        /**
         * The attributes that are mass assignable.
         *
         * @var array
         */
        public function delete($id)
        {
            Post::find($id)->delete();
            session()->flash('message', 'Post Deleted Successfully.');
        }
    }

Step 6: Update Blade Files

Now, create blade file

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>

resources/views/livewire/create.blade.php

<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">Body:</label>
        <textarea type="email" class="form-control" id="exampleFormControlInput2" 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>

resources/views/livewire/update.blade.php

<form>
    <input type="hidden" wire:model="post_id">
    <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">Body:</label>
        <textarea type="email" class="form-control" id="exampleFormControlInput2" 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 7: Update Welcome Blade File

 we will update welcome.blade.php file. in this file we will use @livewireStyles, @livewireScripts and @livewire('contact-form'). so let's add it.

resources/views/welcome.blade.php

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

Run Laravel App:

php artisan serve

Now, Go to web browser, type the URL and see the app output:

http://localhost:8000/