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">
@endif
resources/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 