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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | //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' ); } }; |
php artisan make:controller ProductController
C:\xampp\htdocs\laravel\my-app>php artisan make:controller ProductController
app/Http/Controllers/ProductController.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | //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.' ); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | //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> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | //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> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | //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/web.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | //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' ); }); |
Starting Laravel development server: http://127.0.0.1:8000