Laravel 8 Tutorial - Livewire CRUD

In this tutorial, we are going to learn about Livewire CRUD. So, let's see how we can perform CRUD operations in Livewire.

First of all, let's create a model. Switch to the command prompt and run the following command:


php artisan make:model Student –m

Now, switch to the project and go inside the database directory, then migration. Now, just open the create_student_table migration and add columns as follows:


<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateStudentsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('students', function (Blueprint $table) {
$table->id();
$table->string('firstname');
$table->string('lastname');
$table->string('email');
$table->string('phone');
$table->timestamps();
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('students');
}
}

Now, go to the Student model and write the following code:


<?php

namespace App\Models;

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

class Student extends Model
{
use HasFactory;

protected $table = "students";

protected $fillable = ["firstname","lastname","email","phone"];
}

Now, let's migrate the migration. In the command prompt, just run the command:


php artisan migrate

Now, let's insert some dummy records. For that, just create the Factory. So, in the command prompt, run the command:


php artisan make:factory StudentFactory

Now, open the StudentFactory.php file. For that, just go inside the database directory, then factories. Now, from here, let's open the StudentFactory.php file and write the following code:


<?php

namespace Database\Factories;

use App\Models\Student;
use Illuminate\Database\Eloquent\Factories\Factory;

class StudentFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = Student::class;

/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
return [
'firstname' => $this->faker->firstName,
'lastname' => $this->faker->lastName,
'email' => $this->faker->email,
'phone' => $this->faker->phoneNumber
];
}
}

Now, go to the DatabaseSeeder.php file and add the following code:


\App\Models\Student::factory(10)->create();

Now, run the seeder. So, in the command prompt, just run the command:


php artisan db:seed

Seeding complete, you can see the records. Alright, now let's create a Livewire component:


php artisan make:livewire Students

Now, switch to the project and let's create the route for the Students Component. So, just go inside the routes directory, then web.php. And here, just create a route:


Route::get('/students',Students::class);

Now, just go inside the Students component class file and let's fetch the students' records. So, for that, inside this render method, add the following code:


public function render()
{
$students = Student::orderBy('id','DESC')->get();
return view('livewire.students',['students'=>$students]);
}

Now, just open the students-component.blade.php view file and add the following code:


<div>
@include('livewire.create')
@include('livewire.update')
<section>
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-header">
<div class="row">
<div class="col-md-6">
All Students
</div>
<div class="col-md-6">
<button type="button" class="btn btn-primary float-right" data-toggle="modal" data-target="#addStudentModal">Add New Student</button>
</div>
</div>
</div>
<div class="card-body">
@if(Session::has('message'))
<div class="alert alert-success" role="alert">{{Session::get('message')}}</div>
@endif
<table class="table table-striped">
<thead>
<tr>
<td>First Name</td>
<td>Last Name</td>
<td>Email</td>
<td>Phone</td>
<td>Action</td>
</tr>
</thead>
<tbody>
@foreach($students as $student)
<tr>
<td>{{$student->firstname}}</td>
<td>{{$student->lastname}}</td>
<td>{{$student->email}}</td>
<td>{{$student->phone}}</td>
<td>
<button wire:click="edit({{$student->id}})" class="btn btn-warning btn-sm" data-toggle="modal" data-target="#updateStudentModal">Edit</button>
<button wire:click="delete({{$student->id}})" class="btn btn-danger btn-sm">Delete</button>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</section>
</div>

Now, let's create a layout file, so go inside the resources directory, then views. Then, open the layouts directory. Inside the layouts directory, let's create a new file, which is app.blade.php. Now, in this layout file, add the following code:


<!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 Project</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-Piv4xVNRyMGpqkS2by6br4gNJ7DXjqk09RmUpJ8jgGtD7zP9yug3goQfGII0yAns" crossorigin="anonymous"></script>
@livewireStyles
</head>
<body>
{{$slot}}
@livewireScripts
<script type="text/javascript">
window.livewire.on('studentAdded',()=>{
$('#addStudentModal').modal('hide');
});

window.livewire.on('studentUpdated',()=>{
$('#updateStudentModal').modal('hide');
});
</script>
</body>
</html>

Now, let's create a component view for creating a new student. So, inside the livewire directory, just create a new view file, which name is create.blade.php. Now, inside this file, add the following code:


<div wire:ignore.self class="modal fade" id="addStudentModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<div class="modal-title">
Add New Student
</div>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true close-btn">x</span>
</button>
</div>
<div class="modal-body">
<form >
<div class="form-group">
<label for="firstname">First Name</label>
<input type="text" name="firstname" class="form-control" wire:model="firstname" />
@error('firstname') <span class="text-danger error">{{$message}}</span> @enderror
</div>

<div class="form-group">
<label for="lastname">Last Name</label>
<input type="text" name="lastname" class="form-control" wire:model="lastname" />
@error('lastname') <span class="text-danger error">{{$message}}</span> @enderror
</div>

<div class="form-group">
<label for="email">Email</label>
<input type="text" name="email" class="form-control" wire:model="email" />
@error('email') <span class="text-danger error">{{$message}}</span> @enderror
</div>

<div class="form-group">
<label for="phone">Phone</label>
<input type="text" name="phone" class="form-control" wire:model="phone" />
@error('phone') <span class="text-danger error">{{$message}}</span> @enderror
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary close-btn" data-dismiss="modal">Close</button>
<button type="button" wire:click.prevent="store()" class="btn btn-primary">Save Changes</button>
</div>
</div>
</div>
</div>

Now, go to the Students.php class file and write the following code. First, create properties, then create two functions, one for resetting input fields and another for storing data:


public $firstname;
public $lastname;
public $email;
public $phone;
public $sid;

public function resetInputFields()
{
$this->firstname = '';
$this->lastname = '';
$this->email = '';
$this->phone = '';
}

public function store()
{
$validatedData = $this->validate([
'firstname' => 'required',
'lastname' => 'required',
'email' => 'required|email',
'phone' => 'required'
]);

Student::create($validatedData);
session()->flash('message','Student created Successfully');
$this->resetInputFields();
$this->emit('studentAdded');
}

Now, for updating the record, let's create a new Livewire component view file. Inside the livewire directory, just create a new file, let's say the file name is update.blade.php. Inside this file, let's write the following code:


<div wire:ignore.self class="modal fade" id="updateStudentModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<div class="modal-title">
Update Student
</div>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true close-btn">x</span>
</button>
</div>
<div class="modal-body">
<form >
<div class="form-group">
<label for="firstname">First Name</label>
<input type="text" name="firstname" class="form-control" wire:model="firstname" />
@error('firstname') <span class="text-danger error">{{$message}}</span> @enderror
</div>

<div class="form-group">
<label for="lastname">Last Name</label>
<input type="text" name="lastname" class="form-control" wire:model="lastname" />
@error('lastname') <span class="text-danger error">{{$message}}</span> @enderror
</div>

<div class="form-group">
<label for="email">Email</label>
<input type="text" name="email" class="form-control" wire:model="email" />
@error('email') <span class="text-danger error">{{$message}}</span> @enderror
</div>

<div class="form-group">
<label for="phone">Phone</label>
<input type="text" name="phone" class="form-control" wire:model="phone" />
@error('phone') <span class="text-danger error">{{$message}}</span> @enderror
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary close-btn" data-dismiss="modal">Close</button>
<button type="button" wire:click.prevent="update()" class="btn btn-primary">Save Changes</button>
</div>
</div>
</div>
</div>

Now, let's create two functions in the Students.php class file, one for edit and one for update record:


public function edit($id)
{
$this->updateMode = true;
$student = Student::find($id);
$this->firstname = $student->firstname;
$this->lastname = $student->lastname;
$this->email = $student->email;
$this->phone = $student->phone;
$this->sid = $student->id;
}

public function update()
{
$this->validate([
'firstname' => 'required',
'lastname' => 'required',
'email' => 'required|email',
'phone' => 'required'
]);
if($this->sid){
$student = Student::find($this->sid);
$student->update([
'firstname' => $this->firstname,
'lastname' => $this->lastname,
'email' => $this->email,
'phone' => $this->phone
]);
$this->updateMode = false;
session()->flash('message','Studnet has been updated successfully!');
$this->resetInputFields();
$this->emit('studentUpdated');
}
}

Now, for deleting the record, go to the Students.php class file and create a function for deleting the record:


public function delete($id)
{
if($id)
{
Student::find($id)->delete();
session()->flash('message','Student has been deleted successfully!');
}
}

Now, everything is done. So, switch to the browser and go to the URL /students. And you can see all the students inside the table. If you want to add a new student, then click on the "Add new Student" button, then enter the student details. Now, you can see the new student has been added. You can edit any student record by clicking on the "Edit" button. And for deleting the record, click on the "Delete" button. So, in this way, we can perform CRUD operations in Livewire.