Livewire : CRUD Tutorial in Laravel
Building a Basic CRUD Application with Laravel Livewire
Laravel Livewire is a library that allows you to build dynamic, reactive user interfaces in Laravel using a simple, component-based approach. In this tutorial, we'll create a basic CRUD (Create, Read, Update, Delete) application using Laravel Livewire.
Prerequisites
Before we begin, you should have the following installed on your system:
PHP 7.4 or later
Laravel 8 or later
Composer
Node.js
NPM
Before we get started, you'll need to make sure you have Laravel installed on your system. You can install Laravel using Composer by running the following command:
composer global require laravel/installer
Once you have Laravel installed, you can create a new Laravel project by running the following command:
laravel new project-name
After the project is created, navigate to the project directory and run the following command to install Livewire:
composer require livewire/livewire
Creating the Model
First, we'll create a Product
model that we'll use to store our product data. Run the following command to create the model:
php artisan make:model Product -m
The -m
option will create a migration file for the model.
Next, open the migration file located in database/migrations
and add the following columns to the up
method:
$table->id();
$table->string('name');
$table->text('description');
$table->integer('price');
$table->timestamps();
Once you have added the columns, run the migration to create the products
table in your database:
php artisan migrate
Creating the Livewire Component
Next, we'll create a Livewire component that will handle the creation, reading, updating, and deleting of products. Run the following command to create the component:
php artisan make:livewire Products
This will create a Products
class in the app/Http/Livewire
directory. Open the Products
class and add the following code:
namespace App\Http\Livewire;
use Livewire\Component;
use App\Models\Product;
class Products extends Component
{
public $products, $name, $description, $price, $product_id;
public $isOpen = 0;
public function render()
{
$this->products = Product::all();
return view('livewire.products.index');
}
public function create()
{
$this->resetInputFields();
$this->openModal();
}
public function openModal()
{
$this->isOpen = true;
}
public function closeModal()
{
$this->isOpen = false;
}
private function resetInputFields(){
$this->name = '';
$this->description = '';
$this->price = '';
$this->product_id = '';
}
public function store()
{
$this->validate([
'name' => 'required',
'description' => 'required',
'price' => 'required',
]);
Product::create([
'name' => $this->name,
'description' => $this->description,
'price' => $this->price,
]);
$this->closeModal();
$this->resetInputFields();
}
public function edit($id)
{
$product = Product::findOrFail($id);
$this->product_id = $id;
$this->name = $product->name;
$this->description = $product->description;
$this->price = $product->price;
$this->openModal();
}
public function update()
{
$this->validate([
'name' => 'required',
'description' => 'required',
'price' => 'required',
]);
$product = Product::find($this->product_id);
$product->update([
'name' => $this->name,
'description' => $this->description,
'price' => $this->price,
]);
$this->closeModal();
$this->resetInputFields();
}
public function delete($id)
{
Product::find($id)->delete();
}
}
In this code, we're defining some public properties that we'll use to store data, as well as the render
method which will return the Livewire view that we'll create later. We're also using the Product
model that we created earlier to retrieve all of the products from the database.
Creating the View
Next, we'll create a Livewire view that will display our products and allow us to add, edit, and delete products. Create a new file called index.blade.php
in the resources/views/livewire/products
directory, and add the following code:
<div>
@if($isOpen)
@include('livewire.products.create')
@endif
<button wire:click="create()" class="btn btn-primary mb-3">Add Product</button>
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Description</th>
<th>Price</th>
<th>Action</th>
</tr>
</thead>
<tbody>
@foreach($products as $product)
<tr>
<td>{{ $product->id }}</td>
<td>{{ $product->name }}</td>
<td>{{ $product->description }}</td>
<td>{{ $product->price }}</td>
<td>
<button wire:click="edit({{ $product->id }})" class="btn btn-primary btn-sm">Edit</button>
<button wire:click="delete({{ $product->id }})" class="btn btn-danger btn-sm">Delete</button>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
In this code, we're displaying a table of products, with an "Add Product" button that will open a modal dialog when clicked. We're also using Livewire directives to wire up the "Edit" and "Delete" buttons to their respective methods on the Products
class.
Creating the Modal
Finally, we'll create the modal dialog that will allow us to add and edit products. Create a new file called modal.blade.php
in the resources/views/livewire/products
directory, and add the following code:
<div class="modal fade" wire:ignore.self id="createModal" tabindex="-1" role="dialog" aria-labelledby="createModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="createModalLabel">Add Product</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form>
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" id="name" wire:model="name" placeholder="Enter name">
@error('name') <span class="text-danger">{{ $message }}</span>@enderror
</div>
<div class="form-group">
<label for="description">Description</label>
<textarea class="form-control" id="description" wire:model="description" placeholder="Enter description"></textarea>
@error('description') <span class="text-danger">{{ $message }}</span>@enderror
</div>
<div class="form-group">
<label for="price">Price</label>
<input type="text" class="form-control" id="price" wire:model="price" placeholder="Enter price">
@error('price') <span class="text-danger">{{ $message }}</span>@enderror
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button wire:click.prevent="store()" type="button" class="btn btn-primary">Save</button>
</div>
</div>
</div>
</div>
This file defines a modal form that is used to create a new product. It includes three input fields for the name, description, and price of the product, along with error messages that will be displayed if the user submits invalid data. It also includes buttons to close the modal and save the new product.
Updating the Routes
Now that we have the component and views set up, we need to update the routes to point to the Products
component. Open the web.php
file and update it with the following code:
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Livewire\Products;
Route::get('/', Products::class);
This code sets up the default route to display the Products
component when the user visits the homepage.
Testing the Application
We're now ready to test our CRUD application! Start the development server by running the following command in your terminal:
php artisan serve
Then open your browser and go to http://localhost:8000
. You should see a table with all the products listed.
To add a new product, click the "Add Product" button, fill out the form, and click the "Save" button. The new product should be added to the table.
To edit an existing product, click the "Edit" button next to the product you want to edit, make your changes in the modal form, and click the "Save" button.