Download Laravel App
https://laravel.com/docs/11.x/installation
composer global require laravel/installer
C:\xampp\htdocs\laravel11\myapp>composer global require laravel/installer
Connecting our Database
open .env file root directory.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=8889
DB_DATABASE=laravel11dev
DB_USERNAME=root
DB_PASSWORD=root
Database Migration product
C:\xampp\htdocs\laravel\laravel11\myapp>php artisan make:model Product -m
database/migrations/create_products_table.php
// database/migrations/create_products_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('products', function (Blueprint $table) { $table->id(); $table->string('title'); $table->string('category'); $table->integer('price'); $table->string('image')->nullable(); $table->timestamps(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('products'); } };run this migration
C:\xampp\htdocs\laravel\laravel11\myapp>php artisan migrate
update Product Model
app\Models\Product.php
//app\Models\Product.php <?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Product extends Model { use HasFactory; protected $table = 'products'; protected $fillable = [ 'title', 'category', 'price', 'image', ]; }Create Controller
php artisan make:controller ProductController -r
C:\xampp\htdocs\laravel\laravel10project>php artisan make:controller ProductController -r
app\Http\Controllers\ProductController.php
// <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\Product; use Response; use DataTables; class ProductController extends Controller { public function index() { if (request()->ajax()) { return datatables()->of(Product::select('*')) ->addColumn('action', 'product.product-action') ->addColumn('image', 'product.image') ->rawColumns(['action', 'image']) ->addIndexColumn() ->make(true); } return view('product.home'); } public function store(Request $request) { request()->validate([ 'image' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048', ]); $productId = $request->product_id; $image = $request->hidden_image; if ($files = $request->file('image')) { //delete old file \File::delete('public/product/' . $request->hidden_image); //insert new file $destinationPath = 'public/product/'; // upload path $profileImage = date('YmdHis') . "." . $files->getClientOriginalExtension(); $files->move($destinationPath, $profileImage); $image = "$profileImage"; } $product = Product::find($productId) ?? new Product(); // Set the individual attributes $product->id = $productId; $product->title = $request->title; $product->category = $request->category; $product->price = $request->price; $product->image = $image; // Save the product $product->save(); return Response::json($product); } public function edit($id) { $where = array('id' => $id); $product = Product::where($where)->first(); return Response::json($product); } public function destroy($id) { $data = Product::where('id', $id)->first(['image']); \File::delete('public/product/' . $data->image); $product = Product::where('id', $id)->delete(); return Response::json($product); } }Blade views
Install Yajra Laravel Datatables
https://yajrabox.com/docs/laravel-datatables/10.0
composer require yajra/laravel-datatables-oracle
Bootstrap
https://getbootstrap.com/docs/5.0/
Datatables CDN
https://cdn.datatables.net/1.10.21/
Create blade views
resources/views/product/home.blade.php
//resources/views/product/home.blade.php <!DOCTYPE html> <html lang="en"> <head> <meta name="csrf-token" content="{{ csrf_token() }}"> <title>Laravel 11 CRUD (Create, Read, Update and Delete) Ajax with Upload Image</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script> <script src="https://code.jquery.com/jquery-3.6.1.min.js"></script> <link href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.min.css" rel="stylesheet"> <script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.min.js"></script> </head> <body> <div class="container"> <h1>Laravel 11 CRUD (Create, Read, Update and Delete) Ajax with Upload Image</h1> <a href="javascript:void(0)" class="btn btn-info ml-3" id="create-new-product">Add New</a> <br><br> <table class="table table-bordered table-striped" id="laravel_11_datatable"> <thead> <tr> <th>ID</th> <th>S. No</th> <th>Title</th> <th>Category</th> <th>Price</th> <th>Image</th> <th>Action</th> </tr> </thead> </table> </div> <div class="modal fade" id="ajax-product-modal" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h4 class="modal-title" id="productCrudModal"></h4> </div> <div class="modal-body"> <form id="productForm" name="productForm" class="form-horizontal" enctype="multipart/form-data"> <input type="hidden" name="product_id" id="product_id"> <div class="form-group"> <label for="name" class="col-sm-2 control-label">Title</label> <div class="col-sm-12"> <input type="text" class="form-control" id="title" name="title" placeholder="Enter Tilte" value="" maxlength="50" required=""> </div> </div> <div class="form-group"> <label for="name" class="col-sm-2 control-label">Category</label> <div class="col-sm-12"> <input type="text" class="form-control" id="category" name="category" placeholder="Enter Category" value="" maxlength="50" required=""> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">Price</label> <div class="col-sm-12"> <input type="text" class="form-control" id="price" name="price" placeholder="Enter Price" value="" required=""> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">Image</label> <div class="col-sm-12"> <input id="image" type="file" name="image" accept="image/*" onchange="readURL(this);"> <input type="hidden" name="hidden_image" id="hidden_image"> </div> </div> <img id="modal-preview" src="https://via.placeholder.com/150" alt="Preview" class="form-group hidden" width="100" height="100"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-primary" id="btn-save" value="create">Save changes</button> </div> </form> </div> <div class="modal-footer"> </div> </div> </div> </div> <script> var SITEURL = 'http://127.0.0.1:8000/'; console.log(SITEURL); $(document).ready(function() { $.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } }); $('#laravel_11_datatable').DataTable({ processing: true, serverSide: true, ajax: { url: SITEURL + "products", type: 'GET', }, columns: [{ data: 'id', name: 'id', 'visible': false }, { data: 'DT_RowIndex', name: 'DT_RowIndex', orderable: false, searchable: false }, { data: 'title', name: 'title' }, { data: 'category', name: 'category' }, { data: 'price', name: 'price' }, { data: 'image', name: 'image', orderable: false }, { data: 'action', name: 'action', orderable: false }, ], order: [ [0, 'desc'] ] }); $('#create-new-product').click(function() { $('#btn-save').val("create-product"); $('#product_id').val(''); $('#productForm').trigger("reset"); $('#productCrudModal').html("Add New Product"); $('#ajax-product-modal').modal('show'); $('#modal-preview').attr('src', 'https://via.placeholder.com/150'); }); $('body').on('click', '.edit-product', function() { var product_id = $(this).data('id'); console.log(product_id); $.get('products/Edit/' + product_id, function(data) { $('#title-error').hide(); $('#product_category-error').hide(); $('#category-error').hide(); $('#productCrudModal').html("Edit Product"); $('#btn-save').val("edit-product"); $('#ajax-product-modal').modal('show'); $('#product_id').val(data.id); $('#title').val(data.title); $('#category').val(data.category); $('#price').val(data.price); $('#modal-preview').attr('alt', 'No image available'); if (data.image) { $('#modal-preview').attr('src', SITEURL + 'public/product/' + data.image); $('#hidden_image').attr('src', SITEURL + 'public/product/' + data.image); } }) }); $('body').on('click', '#delete-product', function() { var product_id = $(this).data("id"); if (confirm("Are You sure want to delete !")) { $.ajax({ type: "GET", url: SITEURL + "products/Delete/" + product_id, success: function(data) { var oTable = $('#laravel_11_datatable').dataTable(); oTable.fnDraw(false); }, error: function(data) { console.log('Error:', data); } }); } }); }); $('body').on('submit', '#productForm', function(e) { e.preventDefault(); var actionType = $('#btn-save').val(); $('#btn-save').html('Sending..'); var formData = new FormData(this); $.ajax({ type: 'POST', url: SITEURL + "products/Store", data: formData, cache: false, contentType: false, processData: false, success: (data) => { console.log(data); $('#productForm').trigger("reset"); $('#ajax-product-modal').modal('hide'); $('#btn-save').html('Save Changes'); var oTable = $('#laravel_11_datatable').dataTable(); oTable.fnDraw(false); }, error: function(data) { console.log('Error:', data); $('#btn-save').html('Save Changes'); } }); }); function readURL(input, id) { id = id || '#modal-preview'; if (input.files && input.files[0]) { var reader = new FileReader(); reader.onload = function(e) { $(id).attr('src', e.target.result); }; reader.readAsDataURL(input.files[0]); $('#modal-preview').removeClass('hidden'); $('#start').hide(); } } </script> </body> </html>resources/views/product/image.blade.php
//resources/views/product/image.blade.php @if($image) <img id="preview" src="{{ ('public/product/'.$image) }}" alt="Preview" class="form-group hidden" width="100" height="100"> @else <img id="preview" src="https://via.placeholder.com/150" alt="Preview" class="form-group hidden" width="100" height="100"> @endifresources/views/product/product-action.blade.php
//resources/views/product/product-action.blade.php <a href="javascript:void(0)" data-toggle="tooltip" data-id="{{ $id }}" data-original-title="Edit" class="edit btn btn-success edit-product"> Edit </a> <a href="javascript:void(0);" id="delete-product" data-toggle="tooltip" data-original-title="Delete" data-id="{{ $id }}" class="delete btn btn-danger"> Delete </a>Routes
routes/web.php
// routes/web.php <?php use Illuminate\Support\Facades\Route; use App\Http\Controllers\ProductController; Route::get('/', function () { return view('welcome'); }); Route::get('products', [ProductController::class, 'index']); Route::get('products/Edit/{id}/', [ProductController::class, 'edit']); Route::post('products/Store', [ProductController::class, 'store']); Route::get('products/Delete/{id}', [ProductController::class, 'destroy']);Github - Laravel 11 CRUD (Create, Read, Update and Delete) Ajax with Upload Image