Download Laravel App
https://laravel.com/docs/11.x/installation
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
php artisan make:model Product -m
C:\xampp\htdocs\laravel\my-app>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('name'); $table->string('sku'); $table->double('price', 10, 2); $table->text('description')->nullable(); $table->string('image')->nullable();; $table->timestamps(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('products'); } };Create Controller
php artisan make:controller ProductController
C:\xampp\htdocs\laravel\my-app>php artisan make:controller ProductController
app/Http/Controllers/ProductController.php
//app/Http/Controllers/ProductController.php <?php namespace App\Http\Controllers; use App\Models\Product; //php artisan make:model Product -m use Illuminate\Http\Request; use Illuminate\Support\Facades\File; use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\DB; class ProductController extends Controller { public function index() { //$products = Product::paginate(2); https://laravel.com/docs/11.x/pagination $products = Product::orderBy('created_at', 'DESC')->paginate(3); //$products = Product::orderBy('created_at','DESC')->get(); return view('products.list',[ 'products' => $products ]); } public function search(Request $request) { if (!empty($request)) { $search = $request->input('search'); $products = Product::where( 'name', 'like', "$search%" ) ->orWhere('sku', 'like', "$search%") ->paginate(2); return view('products.list', compact('products')); } $products = DB::table('products') ->orderBy('id', 'DESC') ->paginate(5); return view('products.list', compact('products')); } public function create() { return view('products.create'); } public function store(Request $request) { $rules = [ 'name' => 'required|min:5', 'sku' => 'required|min:3', 'price' => 'required|numeric' ]; if ($request->image != "") { $rules['image'] = 'image'; } $validator = Validator::make($request->all(),$rules); if ($validator->fails()) { return redirect()->route('products.create')->withInput()->withErrors($validator); } // insert product $product = new Product(); $product->name = $request->name; $product->sku = $request->sku; $product->price = $request->price; $product->description = $request->description; $product->save(); if ($request->image != "") { // store image $image = $request->image; $ext = $image->getClientOriginalExtension(); $imageName = time().'.'.$ext; // Unique image name // Save image to products directory $image->move(public_path('uploads/products'),$imageName); // Save image name $product->image = $imageName; $product->save(); } return redirect()->route('products.index')->with('success','Product added successfully.'); } public function edit($id) { $product = Product::findOrFail($id); return view('products.edit',[ 'product' => $product ]); } public function update($id, Request $request) { $product = Product::findOrFail($id); $rules = [ 'name' => 'required|min:5', 'sku' => 'required|min:3', 'price' => 'required|numeric' ]; if ($request->image != "") { $rules['image'] = 'image'; } $validator = Validator::make($request->all(),$rules); if ($validator->fails()) { return redirect()->route('products.edit',$product->id)->withInput()->withErrors($validator); } // update product $product->name = $request->name; $product->sku = $request->sku; $product->price = $request->price; $product->description = $request->description; $product->save(); if ($request->image != "") { // delete old image File::delete(public_path('uploads/products/'.$product->image)); // store image $image = $request->image; $ext = $image->getClientOriginalExtension(); $imageName = time().'.'.$ext; // Unique image name // Save image to products directory $image->move(public_path('uploads/products'),$imageName); // Save image name $product->image = $imageName; $product->save(); } return redirect()->route('products.index')->with('success','Product updated successfully.'); } public function destroy($id) { $product = Product::findOrFail($id); // delete image File::delete(public_path('uploads/products/'.$product->image)); // delete product $product->delete(); return redirect()->route('products.index')->with('success','Product deleted successfully.'); } }View Blade File resources/views/products/list.blade.php
//resources/views/products/list.blade.php <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Laravel 11 CRUD with Upload Image Search and Pagination | Cairocoders</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous"> </head> <body> <div class="bg-primary py-3"> <h3 class="text-white text-center">Laravel 11 CRUD with Upload Image Search and Pagination</h3> </div> <div class="container"> <div class="row justify-content-center mt-4"> <div class="col-md-10 d-flex justify-content-end"> <form method="GET" action="/products/search"> <div class="input-group" style="margin-right:5px;"> <div class="form-outline" data-mdb-input-init> <input class="form-control" name="search" placeholder="Searh..." value="{{ request()->input('search') ? request()->input('search') : '' }}"> </div> <button type="submit" class="btn btn-success">Search</button> </div> </form> <a href="{{ route('products.create') }}" class="btn btn-primary">Create</a> </div> </div> <div class="row d-flex justify-content-center"> @if (Session::has('success')) <div class="col-md-10 mt-4"> <div class="alert alert-success"> {{ Session::get('success') }} </div> </div> @endif <div class="col-md-10"> <div class="card borde-0 shadow-lg my-4"> <div class="card-header bg-primary"> <h3 class="text-white">Products</h3> </div> <div class="card-body"> <table class="table"> <tr> <th>ID</th> <th></th> <th>Name</th> <th>Sku</th> <th>Price</th> <th>Created at</th> <th>Action</th> </tr> @if ($products->isNotEmpty()) @foreach ($products as $product) <tr> <td>{{ $product->id }}</td> <td> @if ($product->image != "") <img width="50" src="{{ asset('uploads/products/'.$product->image) }}" alt=""> @endif </td> <td>{{ $product->name }}</td> <td>{{ $product->sku }}</td> <td>${{ $product->price }}</td> <td>{{ \Carbon\Carbon::parse($product->created_at)->format('d M, Y') }}</td> <td> <a href="{{ route('products.edit',$product->id) }}" class="btn btn-info">Edit</a> <a href="#" onclick="deleteProduct({{ $product->id }});" class="btn btn-danger">Delete</a> <form id="delete-product-from-{{ $product->id }}" action="{{ route('products.destroy',$product->id) }}" method="post"> @csrf @method('delete') </form> </td> </tr> @endforeach @endif </table> {!! $products->withQueryString()->links('pagination::bootstrap-5') !!} </div> </div> </div> </div> </div> <script> function deleteProduct(id) { if (confirm("Are you sure you want to delete product?")) { document.getElementById("delete-product-from-" + id).submit(); } } </script> </body> </html>resources/views/products/create.blade.php
//resources/views/products/create.blade.php <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Laravel 11 CRUD with Upload Image Search and Pagination | Cairocoders</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous"> </head> <body> <div class="bg-primary py-3"> <h3 class="text-white text-center">Laravel 11 CRUD with Upload Image Search and Pagination</h3> </div> <div class="container"> <div class="row justify-content-center mt-4"> <div class="col-md-10 d-flex justify-content-end"> <a href="{{ route('products.index') }}" class="btn btn-primary">Back</a> </div> </div> <div class="row d-flex justify-content-center"> <div class="col-md-10"> <div class="card borde-0 shadow-lg my-4"> <div class="card-header bg-primary"> <h3 class="text-white">Create Product</h3> </div> <form enctype="multipart/form-data" action="{{ route('products.store') }}" method="post"> @csrf <div class="card-body"> <div class="mb-3"> <label for="" class="form-label h5">Name</label> <input value="{{ old('name') }}" type="text" class="@error('name') is-invalid @enderror form-control-lg form-control" placeholder="Name" name="name"> @error('name') <p class="invalid-feedback">{{ $message }}</p> @enderror </div> <div class="mb-3"> <label for="" class="form-label h5">Sku</label> <input value="{{ old('sku') }}" type="text" class="@error('sku') is-invalid @enderror form-control form-control-lg" placeholder="Sku" name="sku"> @error('sku') <p class="invalid-feedback">{{ $message }}</p> @enderror </div> <div class="mb-3"> <label for="" class="form-label h5">Price</label> <input value="{{ old('price') }}" type="text" class="@error('price') is-invalid @enderror form-control form-control-lg" placeholder="Price" name="price"> @error('price') <p class="invalid-feedback">{{ $message }}</p> @enderror </div> <div class="mb-3"> <label for="" class="form-label h5">Description</label> <textarea placeholder="Description" class="form-control" name="description" cols="30" rows="5">{{ old('description') }}</textarea> </div> <div class="mb-3"> <label for="" class="form-label h5">Image</label> <input type="file" class="form-control form-control-lg" placeholder="Price" name="image"> </div> <div class="d-grid"> <button class="btn btn-lg btn-primary">Submit</button> </div> </div> </form> </div> </div> </div> </div> </body> </html>resources/views/products/edit.blade.php
//resources/views/products/edit.blade.php <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Laravel 11 CRUD with Upload Image Search and Pagination | Cairocoders</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous"> </head> <body> <div class="bg-primary py-3"> <h3 class="text-white text-center">Laravel 11 CRUD with Upload Image Search and Pagination</h3> </div> <div class="container"> <div class="row justify-content-center mt-4"> <div class="col-md-10 d-flex justify-content-end"> <a href="{{ route('products.index') }}" class="btn btn-primary">Back</a> </div> </div> <div class="row d-flex justify-content-center"> <div class="col-md-10"> <div class="card borde-0 shadow-lg my-4"> <div class="card-header bg-primary"> <h3 class="text-white">Edit Product</h3> </div> <form enctype="multipart/form-data" action="{{ route('products.update',$product->id) }}" method="post"> @method('put') @csrf <div class="card-body"> <div class="mb-3"> <label for="" class="form-label h5">Name</label> <input value="{{ old('name',$product->name) }}" type="text" class="@error('name') is-invalid @enderror form-control-lg form-control" placeholder="Name" name="name"> @error('name') <p class="invalid-feedback">{{ $message }}</p> @enderror </div> <div class="mb-3"> <label for="" class="form-label h5">Sku</label> <input value="{{ old('sku',$product->sku) }}" type="text" class="@error('sku') is-invalid @enderror form-control form-control-lg" placeholder="Sku" name="sku"> @error('sku') <p class="invalid-feedback">{{ $message }}</p> @enderror </div> <div class="mb-3"> <label for="" class="form-label h5">Price</label> <input value="{{ old('price',$product->price) }}" type="text" class="@error('price') is-invalid @enderror form-control form-control-lg" placeholder="Price" name="price"> @error('price') <p class="invalid-feedback">{{ $message }}</p> @enderror </div> <div class="mb-3"> <label for="" class="form-label h5">Description</label> <textarea placeholder="Description" class="form-control" name="description" cols="30" rows="5">{{ old('description',$product->description) }}</textarea> </div> <div class="mb-3"> <label for="" class="form-label h5">Image</label> <input type="file" class="form-control form-control-lg" placeholder="Price" name="image"> @if ($product->image != "") <img class="w-50 my-3" src="{{ asset('uploads/products/'.$product->image) }}" alt=""> @endif </div> <div class="d-grid"> <button class="btn btn-lg btn-primary">Update</button> </div> </div> </form> </div> </div> </div> </div> </body> </html>Routes
routes/web.php
//routes/web.php <?php use Illuminate\Support\Facades\Route; use App\Http\Controllers\ProductController; //php artisan make:controller ProductController Route::get('/', function () { return view('welcome'); }); Route::controller(ProductController::class)->group(function () { Route::get('/products', 'index')->name('products.index'); Route::get('/products/create', 'create')->name('products.create'); Route::post('/products', 'store')->name('products.store'); Route::get('/products/{product}/edit', 'edit')->name('products.edit'); Route::put('/products/{product}', 'update')->name('products.update'); Route::delete('/products/{product}', 'destroy')->name('products.destroy'); Route::get('/products/search', 'search')->name('search'); });Run C:\xampp\htdocs\laravel\my-app>php artisan serve
Starting Laravel development server: http://127.0.0.1:8000