Download Laravel App
composer create-project --prefer-dist laravel/laravel my-app
C:\xampp\htdocs\laravel10project>composer create-project laravel/laravel laravel10project
Connecting our Database
open .env file root directory.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laraveldb
DB_USERNAME=root
DB_PASSWORD=
Create Model and Migration
C:\xampp\htdocs\laravel\laravelproject>php artisan make:model Employee -m
A new file named Employee.php will be created in the app directory and database/migrations directory to generate the table in our database
app/Models/Employee.php
//app/Models/Employee.php <?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Employee extends Model { use HasFactory; protected $fillable = [ 'first_name', 'last_name', 'email', 'avatar' ]; }database\migrations\create_employees_table.php
//database\migrations\create_employees_table.php <?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { /** * Run the migrations. */ public function up(): void { Schema::create('employees', function (Blueprint $table) { $table->id(); $table->string('first_name'); $table->string('last_name'); $table->string('email'); $table->string('avatar'); $table->timestamps(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('employees'); } };Database Migration
php artisan migrate
C:\xampp\htdocs\laravel\laravel10project>php artisan migrate
Migration table created successfully.
check database table
Create Controller
php artisan make:controller EmployeeController
C:\xampp\htdocs\laravel\my-app>php artisan make:controller EmployeeController
app/Http/Controllers/EmployeeController.php
// <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\Employee; use Illuminate\Support\Facades\Storage; class EmployeeController extends Controller { public function index() { return view('index'); } public function fetchAll() { $employee = Employee::all(); $output = ''; if ($employee->count() > 0) { $output .= '<table class="table table-striped align-middle"> <thead> <tr> <th>ID</th> <th>Avatar</th> <th>Name</th> <th>E-mail</th> <th>Action</th> </tr> </thead> <tbody>'; foreach ($employee as $rs) { $output .= '<tr> <td>' . $rs->id . '</td> <td><img src="storage/images/' . $rs->avatar . '" width="50" class="img-thumbnail rounded-circle"></td> <td>' . $rs->first_name . ' ' . $rs->last_name . '</td> <td>' . $rs->email . '</td> <td> <a href="#" id="' . $rs->id . '" class="text-success mx-1 editIcon" data-bs-toggle="modal" data-bs-target="#editEmployeeModal"><i class="bi-pencil-square h4"></i></a> <a href="#" id="' . $rs->id . '" class="text-danger mx-1 deleteIcon"><i class="bi-trash h4"></i></a> </td> </tr>'; } $output .= '</tbody></table>'; echo $output; } else { echo '<h1 class="text-center text-secondary my-5">No record in the database!</h1>'; } } // insert a new employee ajax request public function store(Request $request) { $file = $request->file('avatar'); $fileName = time() . '.' . $file->getClientOriginalExtension(); $file->storeAs('public/images', $fileName); //php artisan storage:link $empData = ['first_name' => $request->fname, 'last_name' => $request->lname, 'email' => $request->email, 'avatar' => $fileName]; Employee::create($empData); return response()->json([ 'status' => 200, ]); } // edit an employee ajax request public function edit(Request $request) { $id = $request->id; $emp = Employee::find($id); return response()->json($emp); } // update an employee ajax request public function update(Request $request) { $fileName = ''; $emp = Employee::find($request->emp_id); if ($request->hasFile('avatar')) { $file = $request->file('avatar'); $fileName = time() . '.' . $file->getClientOriginalExtension(); $file->storeAs('public/images', $fileName); if ($emp->avatar) { Storage::delete('public/images/' . $emp->avatar); } } else { $fileName = $request->emp_avatar; } $empData = ['first_name' => $request->fname, 'last_name' => $request->lname, 'email' => $request->email, 'avatar' => $fileName]; $emp->update($empData); return response()->json([ 'status' => 200, ]); } // delete an employee ajax request public function delete(Request $request) { $id = $request->id; $emp = Employee::find($id); if (Storage::delete('public/images/' . $emp->avatar)) { Employee::destroy($id); } } }View Blade
Bootstrap 5
https://getbootstrap.com/docs/5.0/getting-started/introduction/
https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css
Jquery
https://jquery.com/download/
CDN : jsDelivr CDN
https://www.jsdelivr.com/package/npm/jquery
Datatables
DataTables is a plug-in for the jQuery Javascript library. It is a highly flexible tool, built upon the foundations of progressive enhancement, that adds all of these advanced features to any HTML table.
https://datatables.net/
sweetalert2
A BEAUTIFUL, RESPONSIVE, CUSTOMIZABLE, ACCESSIBLE (WAI-ARIA) REPLACEMENT FOR JAVASCRIPT'S POPUP BOXES
https://sweetalert2.github.io/
resources/views/index.blade.php
//resources/views/index.blade.php <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="csrf-token" content="{{ csrf_token() }}"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Laravel 10 CRUD With Image Upload using jQuery Ajax with SweetAlert and DataTables</title> <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css' /> <link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/bootstrap-icons/1.5.0/font/bootstrap-icons.min.css' /> <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.13.4/css/jquery.dataTables.min.css" /> </head> <body> <div class="container"> <div class="row my-5"> <div class="col-lg-12"> <h2>Laravel 10 CRUD With Image Upload using jQuery Ajax with SweetAlert and DataTables</h2> <div class="card shadow"> <div class="card-header d-flex justify-content-between align-items-center"> <h3 class="text-light">Manage Employees</h3> <button class="btn btn-light" data-bs-toggle="modal" data-bs-target="#addEmployeeModal"><i class="bi-plus-circle me-2"></i>Add New Employee</button> </div> <div class="card-body" id="show_all_employees"> <h1 class="text-center text-secondary my-5">Loading...</h1> </div> </div> </div> </div> </div> {{-- new employee modal --}} <div class="modal fade" id="addEmployeeModal" tabindex="-1" aria-labelledby="exampleModalLabel" data-bs-backdrop="static" aria-hidden="true"> <div class="modal-dialog modal-dialog-centered"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="exampleModalLabel">Add New Employee</h5> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <form action="#" method="POST" id="add_employee_form" enctype="multipart/form-data"> @csrf <div class="modal-body p-4 bg-light"> <div class="row"> <div class="col-lg"> <label for="fname">First Name</label> <input type="text" name="fname" class="form-control" placeholder="First Name" required> </div> <div class="col-lg"> <label for="lname">Last Name</label> <input type="text" name="lname" class="form-control" placeholder="Last Name" required> </div> </div> <div class="my-2"> <label for="email">E-mail</label> <input type="email" name="email" class="form-control" placeholder="E-mail" required> </div> <div class="my-2"> <label for="avatar">Select Avatar</label> <input type="file" name="avatar" class="form-control" required> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> <button type="submit" id="add_employee_btn" class="btn btn-primary">Add Employee</button> </div> </form> </div> </div> </div> {{-- edit employee modal --}} <div class="modal fade" id="editEmployeeModal" tabindex="-1" aria-labelledby="exampleModalLabel" data-bs-backdrop="static" aria-hidden="true"> <div class="modal-dialog modal-dialog-centered"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="exampleModalLabel">Edit Employee</h5> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <form action="#" method="POST" id="edit_employee_form" enctype="multipart/form-data"> @csrf <input type="hidden" name="emp_id" id="emp_id"> <input type="hidden" name="emp_avatar" id="emp_avatar"> <div class="modal-body p-4 bg-light"> <div class="row"> <div class="col-lg"> <label for="fname">First Name</label> <input type="text" name="fname" id="fname" class="form-control" placeholder="First Name" required> </div> <div class="col-lg"> <label for="lname">Last Name</label> <input type="text" name="lname" id="lname" class="form-control" placeholder="Last Name" required> </div> </div> <div class="my-2"> <label for="email">E-mail</label> <input type="email" name="email" id="email" class="form-control" placeholder="E-mail" required> </div> <div class="my-2"> <label for="avatar">Select Avatar</label> <input type="file" name="avatar" class="form-control"> </div> <div class="mt-2" id="avatar"></div> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> <button type="submit" id="edit_employee_btn" class="btn btn-success">Update Employee</button> </div> </form> </div> </div> </div> <script src='https://cdn.jsdelivr.net/npm/jquery@3.7.0/dist/jquery.min.js'></script> <script src='https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js'></script> <script type="text/javascript" src="https://cdn.datatables.net/1.13.4/js/jquery.dataTables.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script> <script> $(function() { // add new employee ajax request $("#add_employee_form").submit(function(e) { e.preventDefault(); const fd = new FormData(this); $("#add_employee_btn").text('Adding...'); $.ajax({ url: '{{ route('store') }}', method: 'post', data: fd, cache: false, contentType: false, processData: false, dataType: 'json', success: function(response) { if (response.status == 200) { Swal.fire( 'Added!', 'Employee Added Successfully!', 'success' ) fetchAllEmployees(); } $("#add_employee_btn").text('Add Employee'); $("#add_employee_form")[0].reset(); $("#addEmployeeModal").modal('hide'); } }); }); // edit employee ajax request $(document).on('click', '.editIcon', function(e) { e.preventDefault(); let id = $(this).attr('id'); $.ajax({ url: '{{ route('edit') }}', method: 'get', data: { id: id, _token: '{{ csrf_token() }}' }, success: function(response) { $("#fname").val(response.first_name); $("#lname").val(response.last_name); $("#email").val(response.email); $("#avatar").html( `<img src="storage/images/${response.avatar}" width="100" class="img-fluid img-thumbnail">`); $("#emp_id").val(response.id); $("#emp_avatar").val(response.avatar); } }); }); // update employee ajax request $("#edit_employee_form").submit(function(e) { e.preventDefault(); const fd = new FormData(this); $("#edit_employee_btn").text('Updating...'); $.ajax({ url: '{{ route('update') }}', method: 'post', data: fd, cache: false, contentType: false, processData: false, dataType: 'json', success: function(response) { if (response.status == 200) { Swal.fire( 'Updated!', 'Employee Updated Successfully!', 'success' ) fetchAllEmployees(); } $("#edit_employee_btn").text('Update Employee'); $("#edit_employee_form")[0].reset(); $("#editEmployeeModal").modal('hide'); } }); }); // delete employee ajax request $(document).on('click', '.deleteIcon', function(e) { e.preventDefault(); let id = $(this).attr('id'); let csrf = '{{ csrf_token() }}'; Swal.fire({ title: 'Are you sure?', text: "You won't be able to revert this!", icon: 'warning', showCancelButton: true, confirmButtonColor: '#3085d6', cancelButtonColor: '#d33', confirmButtonText: 'Yes, delete it!' }).then((result) => { if (result.isConfirmed) { $.ajax({ url: '{{ route('delete') }}', method: 'delete', data: { id: id, _token: csrf }, success: function(response) { console.log(response); Swal.fire( 'Deleted!', 'Your file has been deleted.', 'success' ) fetchAllEmployees(); } }); } }) }); // fetch all employees ajax request fetchAllEmployees(); function fetchAllEmployees() { $.ajax({ url: '{{ route('fetchAll') }}', method: 'get', success: function(response) { $("#show_all_employees").html(response); $("table").DataTable({ order: [0, 'desc'] }); } }); } }); </script> </body> </html>Routes
routes/web.php
//routes/web.php <?php use Illuminate\Support\Facades\Route; use App\Http\Controllers\AuthController; use App\Http\Controllers\EmployeeController; //Route::get('/', function () { // return view('welcome'); //}); Route::get('/', [EmployeeController::class, 'index']); Route::post('/store', [EmployeeController::class, 'store'])->name('store'); Route::get('/fetchall', [EmployeeController::class, 'fetchAll'])->name('fetchAll'); Route::delete('/delete', [EmployeeController::class, 'delete'])->name('delete'); Route::get('/edit', [EmployeeController::class, 'edit'])->name('edit'); Route::post('/update', [EmployeeController::class, 'update'])->name('update');Run C:\xampp\htdocs\laravel\my-app>php artisan serve
Starting Laravel development server: http://127.0.0.1:8000