Laravel 10 Ajax jQuery Crud with Pagination and Live Search

Laravel 10 Ajax jQuery Crud with Pagination and Live Search

Laravel is a popular PHP web framework that provides developers with a wide range of features for building web applications. One of the most common tasks when building a web application is the implementation of CRUD (Create, Read, Update, Delete) operations. In this article, we will look at how to implement a Laravel CRUD application with pagination that uses jQuery and Ajax. For build a laravel ajax crud applicaion we need to follow the bellow steps.

 

 

Step 1. Setting up the Laravel Application

 

To get started, we need to create a new Laravel project using the command-line interface. Open up your terminal and type the following command:

composer create-project --prefer-dist laravel/laravel laravel-ajax-jquery-crud

This will create a new Laravel project in a folder called laravel-ajax-jquery-crud. Once the project has been created, we need to create a new database and configure our .env file with our database credentials.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel-ajax-jquery-crud
DB_USERNAME=root
DB_PASSWORD=

 

Step 2. Creating the Database Table and Model

 

Next, we need to create a new migration for the products table. Run the following command in the terminal:

php artisan make:migration create_products_table --create=products

This command will generate a new migration file for us. Open the migration file located in database/migrations and add the necessary columns for the products table.

 public function up()
    {
        Schema::create('products', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->double('price');
            $table->timestamps();
        });
    }

Once you have defined your migration, run the migration to create the products table in your database:

php artisan migrate

 

 

Step 3. Creating the Product Model

 

Now that we have our database table set up, we need to create a model for our products table. Run the following command to generate a new model for the products table:

php artisan make:model Product

This command will create a new Product model in the app/Models directory.

 

Step 4. Defining the Product Controller

 

With our database table and model created, we can now create a controller. Run the following command to generate a new controller for the products:

php artisan make:controller ProductController

This command will create a new ProductController in the app/Http/Controllers directory. Open the ProductController and add the necessary methods for handling the CRUD operations.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Product;

class ProductController extends Controller
{
    public function products()
    {
        $products = Product::latest()->paginate(5);
        return view('products',compact('products'));
    }

    //paginate product 
    function paginateData(Request $request)
    {
     if($request->ajax())
     {
      $products = Product::latest()->paginate(5);
      return view('pagination_products', compact('products'))->render();
     }
    }

  
   //store product
    public function addProduct(Request $request)
    {
        $request->validate(
            [
                'name'=>'required',
                'price'=>'required',
            ],
            [
                'name.required'=>'Product Name is Required',
                'price.required'=>'Product Price is Required',
            ]
        );
        
        $product = new Product();
        $product->name = $request->name;
        $product->price = $request->price;
        $product->save();

        return response()->json([
            'status'=>'success',
        ]);
    }


    //update product 
    public function updateProduct(Request $request)
    {
        $request->validate(
            [
                'up_name'=>'required',
                'up_price'=>'required',
            ],
            [
                'up_name.required'=>'Product Name is Required',
                'up_price.required'=>'Product Price is Required',
            ]
        );
        
        Product::where('id',$request->up_id)
        ->update(['name'=>$request->up_name,'price'=>$request->up_price]);

        return response()->json([
            'status'=>'success',
        ]);
    }

    //delete product 
    public function deleteProduct(Request $request)
    {
        Product::find($request->product_id)->delete();
        return response()->json([
            'status'=>'success',
        ]);
    }



    //search product 
    public function searchProduct(Request $request)
    {
        $products = Product::where('name', 'like', '%'.$request->search_string.'%')
        ->orWhere('price', 'like', '%'.$request->search_string.'%')
        ->orderBy('id', 'desc')
        ->paginate(5);

        if($products->count() >= 1){
            return view('pagination_products', compact('products'))->render();
        }else{
            return response()->json([
                'status'=>'nothing found'
            ]);
        }
        
    }

}

 

 

Step 5. Defining the blade files

 

Now we will create all the required blade files at resources/views directory.

products.blade.php

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <link rel="stylesheet" href="https://maxst.icons8.com/vue-static/landings/line-awesome/line-awesome/1.3.0/css/line-awesome.min.css">
    <link rel="stylesheet" href="http://cdn.bootcss.com/toastr.js/latest/css/toastr.min.css">
    <title>Ajax Crud</title>
  </head>
  <body>
    <div class="container">
        <div class="row">
            <div class="col-md-2"></div>
            <div class="col-md-8">
                <h4 class="text-center mt-5">Laravel <strong>9</strong> Ajax Crud</h4>
                <a href="" class="btn btn-info my-3 text-right" data-bs-toggle="modal" data-bs-target="#addModal">Add Product</a>
                <input type="text" name="search" id="search" class="form-control mb-3" placeholder="Search Here.....">
                <div class="table-data">
                  <table class="table table-bordered">
                    <thead>
                      <tr>
                        <th scope="col">#</th>
                        <th scope="col">Name</th>
                        <th scope="col">Price</th>
                        <th scope="col">Action</th>
                      </tr>
                    </thead>
                    <tbody>
                      @foreach($products as $key=>$pro)
                      <tr>
                        <td>{{ $key+1 }}</td>
                        <td>{{ $pro->name }}</td>
                        <td>{{ $pro->price }}</td>
                        <td>
                            <a href="" 
                            class="btn btn-success edit_product_form"
                            data-bs-toggle="modal" 
                            data-bs-target="#editModal"
                            data-id="{{  $pro->id }}"
                            data-name="{{  $pro->name }}"
                            data-price="{{  $pro->price }}"
                            >
                              <i class="las la-edit"></i>
                            </a>
                            <a href="" data-product_id="{{ $pro->id }}" class="btn btn-danger delete_product">
                              <i class="las la-times"></i>
                            </a>
                        </td>
                      </tr>
                      @endforeach
                    </tbody>
                  </table>
                  {!! $products->links() !!}
                </div>
                  
            </div>
        </div>
    </div>
    
    @include('add_product_modal')
    @include('edit_product_modal')
    @include('product_js')
    {!! Toastr::message() !!}
  </body>
</html>

 

add_product_modal.blade.php

<!-- Modal -->
<div class="modal fade" id="addModal" tabindex="-1" aria-labelledby="addModalLabel" aria-hidden="true">
    <div class="modal-dialog">
      <form action="{{ url('add-product') }}" method="post" id="addProductForm">
        @csrf
      <div class="modal-content">
        <div class="modal-header">
          <h5 class="modal-title" id="addModalLabel">Add Product</h5>
          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
        </div>
        <div class="modal-body">
          <div class="errorMsgntainer mb-3">
          </div>
         
            <div class="form-group">
              <label for="product_name">Name</label>
              <input type="text" name="name" id="name" class="form-control">
            </div>
            <div class="form-group mt-2">
              <label for="product_price">Price</label>
              <input type="number" name="price" id="price" class="form-control">
            </div>
          
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
          <button type="submit" class="btn btn-primary add_product">Save changes</button>
        </div>
      </div>
    </form>
    </div>
  </div>

 

edit_product_modal.blade.php

<!-- Modal -->
<div class="modal fade" id="editModal" tabindex="-1" aria-labelledby="editModalLabel" aria-hidden="true">
    <div class="modal-dialog">
      <form action="{{ url('store-product') }}" method="post" id="editProductForm">
        @csrf
      <div class="modal-content">
        <div class="modal-header">
          <h5 class="modal-title" id="editModalLabel">Edit Product</h5>
          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
        </div>
        <div class="modal-body">
          <div class="errorMsgntainer mb-3">
          </div>
            <input type="hidden" name="up_id" id="up_id">
            <div class="form-group">
              <label for="up_name">Name</label>
              <input type="text" name="up_name" id="up_name" class="form-control">
            </div>
            <div class="form-group mt-2">
              <label for="up_price">Price</label>
              <input type="number" name="up_price" id="up_price" class="form-control">
            </div>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
          <button type="submit" class="btn btn-primary store_product">Save changes</button>
        </div>
      </div>
      </form>
    </div>
  </div>

 

product_js.blade.php

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script src="http://cdn.bootcss.com/toastr.js/latest/js/toastr.min.js"></script>
<script>
  $.ajaxSetup({
  headers: {
      'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }
});
</script>

<script>
  $(document).ready(function(){
    //add product
    $(document).on('click','.add_product',function(e){
      e.preventDefault();
      let name = $('#name').val();
      let price = $('#price').val();
      // console.log(name+price);
      $.ajax({
        method:'post',
        url:'{{ route('add.product') }}',
        data:{
          name:name,price:price,
        },
        success:function(res){
          if(res.status=='success'){
            $('#addProductForm')[0].reset();
            $('#addModal').modal('hide');
            $('.table').load(location.href + ' .table');
              Command: toastr["success"]("Product Added Success !!", "Success")
              toastr.options = {
              "closeButton": true,
              "debug": false,
              "newestOnTop": false,
              "progressBar": true,
              "positionClass": "toast-top-right",
              "preventDuplicates": false,
              "onclick": null,
              "showDuration": "300",
              "hideDuration": "1000",
              "timeOut": "5000",
              "extendedTimeOut": "1000",
              "showEasing": "swing",
              "hideEasing": "linear",
              "showMethod": "fadeIn",
              "hideMethod": "fadeOut"
              }
          }
        },
        error:function(err){
          let error = err.responseJSON;
          $.each(error.errors, function (index, value) {
            $('.errorMsgntainer').append('<span class="text-danger">'+value+'<span>'+'<br>');
          });
        }
      });
    })
    //product show in edit form
    $(document).on('click','.edit_product_form',function(){
        let up_id = $(this).data('id');
        let up_name = $(this).data('name');
        let up_price = $(this).data('price');
        
        $('#up_id').val(up_id);
        $('#up_name').val(up_name);
        $('#up_price').val(up_price);
    })
    //update product
    $(document).on('click','.update_product',function(e){
      e.preventDefault();
      let up_id = $('#up_id').val();
      let up_name = $('#up_name').val();
      let up_price = $('#up_price').val();
      // console.log(name+price);
      $.ajax({
        method:'post',
        url:'{{ route('update.product') }}',
        data:{
          up_id:up_id,up_name:up_name,up_price:up_price,
        },
        success:function(res){
          if(res.status=='success'){
            $('#editProductForm')[0].reset();
            $('#editModal').modal('hide');
            $('.table').load(location.href + ' .table');
              Command: toastr["success"]("Product Updated Success !!", "Success")
              toastr.options = {
              "closeButton": true,
              "debug": false,
              "newestOnTop": false,
              "progressBar": true,
              "positionClass": "toast-top-right",
              "preventDuplicates": false,
              "onclick": null,
              "showDuration": "300",
              "hideDuration": "1000",
              "timeOut": "5000",
              "extendedTimeOut": "1000",
              "showEasing": "swing",
              "hideEasing": "linear",
              "showMethod": "fadeIn",
              "hideMethod": "fadeOut"
              }
          }
        },
        error:function(err){
          let error = err.responseJSON;
          $.each(error.errors, function (index, value) {
            $('.errorMsgntainer').append('<span class="text-danger">'+value+'<span>'+'<br>');
          });
        }
      });
    })
    //delete product 
    $(document).on('click','.delete_product',function(e){
      e.preventDefault();
       if(confirm('Are you sure to delete')){
        let product_id = $(this).data('product_id');
        // console.log(product_id);
        $.ajax({
          url:"{{ route('delete.product') }}",
          method:'post',
          data:{product_id:product_id},
          success:function(res){
            if(res.status=='success'){
              // console.log('Delete Success');
              $('.table').load(location.href + ' .table');
              Command: toastr["warning"]("Product Delete Success !!", "Success")
              toastr.options = {
              "closeButton": true,
              "debug": false,
              "newestOnTop": false,
              "progressBar": true,
              "positionClass": "toast-top-right",
              "preventDuplicates": false,
              "onclick": null,
              "showDuration": "300",
              "hideDuration": "1000",
              "timeOut": "5000",
              "extendedTimeOut": "1000",
              "showEasing": "swing",
              "hideEasing": "linear",
              "showMethod": "fadeIn",
              "hideMethod": "fadeOut"
              }
            }
          }
        });
      }
    })
    //pagination 
    $(document).on('click', '.pagination a', function(e){
      e.preventDefault(); 
      var page = $(this).attr('href').split('page=')[1];
      products(page);
    });
    function products(page){
      $.ajax({
      url:"/pagination/paginate-data?page="+page,
      // url:"{{ route('paginate.product').'?page='.'page'}}",
      success:function(res){
        $('.table-data').html(res);
        }
      });
    }
    //search product 
    $(document).on('keyup',function(e){
      e.preventDefault();
       let search_string = $('#search').val();
       $.ajax({
         url:"{{ route('search.product') }}",
         method:'GET',
         data:{search_string:search_string},
         success:function(res){
          $('.table-data').html(res);
          if(res.status=='nothing found'){
            $('.table-data').html('<span class="text-danger">'+'Nothing Found'+'</span>');
          }
         }
       });
    })
  })
</script>

 

 

pagination_products.blade.php

<table class="table table-bordered">
    <thead>
      <tr>
        <th scope="col">#</th>
        <th scope="col">Name</th>
        <th scope="col">Price</th>
        <th scope="col">Action</th>
      </tr>
    </thead>
    <tbody>
      @foreach($products as $key=>$pro)
      <tr>
        <td>{{ $key+1 }}</td>
        <td>{{ $pro->name }}</td>
        <td>{{ $pro->price }}</td>
        <td>
            <a href="" 
            class="btn btn-success edit_product_form"
            data-bs-toggle="modal" 
            data-bs-target="#editModal"
            data-id="{{  $pro->id }}"
            data-name="{{  $pro->name }}"
            data-price="{{  $pro->price }}"
            >
              <i class="las la-edit"></i>
            </a>
            <a href="" data-product_id="{{ $pro->id }}" class="btn btn-danger delete_product">
              <i class="las la-times"></i>
            </a>
        </td>
      </tr>
      @endforeach
    </tbody>
  </table>
  {!! $products->links() !!}

 

 

Step 6. Defining the routes in web.php

 

Now we have to define all the routes inside web.php file

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ProductController;


Route::get('/',[ProductController::class,'products']);
Route::post('/add-product',[ProductController::class,'addProduct'])->name('add.product');
Route::post('/update-product',[ProductController::class,'updateProduct'])->name('update.product');
Route::post('/delete-product',[ProductController::class,'deleteProduct'])->name('delete.product');
Route::get('pagination/paginate-data',[ProductController::class,'paginateData'])->name('paginate.product');
Route::get('/search-product',[ProductController::class,'searchProduct'])->name('search.product');

 

Now run the following command to start development serverand test the crud application:

php artisan serve

 

Thanks. Hope this wil help you a lot.

 

 

 

If you like what you are reading, please think about buying us a coffee as a token of appreciation.

Buy Me A Coffee

We appreciate your support and are committed to providing you useful and informative content.

We are thankful for your ongoing support.

 

 

 

You May Read Bellow Articles:

 

 

Laravel 9 live search data in a table using ajax

 

How to send SMS in laravel 9 using Twilio SMS API-Webjourney

 

Laravel 9 pdf invoice generate and download with barryvdh dompdf

 

How to create multi language website by laravel 9

 

Laravel 10 multiple form validation on the same page-WebJourney

 

 Laravel 10 Breeze Authentication - WebJourney

 

Laravel 10 Ajax jQuery Crud with Pagination and Live Search

 

Laravel Naming Conventions Accepted by Laravel community

 

Laravel Shorter and More Readable Syntax - WebJourney

 

Tags

  • Share This: