Filtering and ajax loading

  • Code

    1. Route

    Normally we need one route for loading a full page (header , footer and content).
    But here we need 2 routes, one for first loading with full layout(header, footer , left panel and product listing). Second route for loading only the product listing (without header , footer and left panel)

    
                        // for first loading  with full layout
                        Route::get('/product', [ProductController::class,'productList'])->name('product');
    
                        //for ajax loading with partial page
                        Route::get('/product/ajax', [ProductController::class,'partialProductList'])->name('product.ajax');
                        

    2. controller

    add functions for first loading and ajax loading

    
                          //for first loading with full layout
                          public function productList(Request $request){
    
                            return view('fe.products.index');
                          }
    
                          //for ajax loading with product listing only
                         public function partialProductList(Request $request){
                             
                             
                         }
                        

    3. create index.blade extended from master layout

    fe.products.index.blade.php

    
                              
                              extends('fe.layouts.master')
    
                              <div calss="col-4">
                                  here is html code for product
                              <div>
                              <div calss="col-4">
                                  here is html code for product
                              <div>
                              <div calss="col-4">
                                  here is html code for product
                              <div>
                              <div id="latest_product_panel"> 
                                include('fe.products.partial_productlist')
                              </div>
                              
                        

    write the html code for filtering in the left panel of index.blade or master.blade

    
                              <form id="filterPanel">
                                    <label>Sort by</label>
                                    <select class="filter_sorting" name="sorting"> </select>
                                    
                                    <label>Category</label>
                                    <input type="checkbox" class="filter_category" name="categoryId[]">Category1
                                    <input type="checkbox" class="filter_category" name="categoryId[]">Category1
                                    
                                    
                                    <label>Price Range</label>
                                    <input type="radio" class="filter_price" name="price">1-100
                                    <input type="radio" class="filter_price" name="price">100-200
    
    
                                  <div id="latest_product_panel"> 
                                    include('fe.products.partial_productlist')
                                  </div>
                              </form>
                        
    1. class="filter_category" for using in jquery
    2. array of name="categoryId[]" for sending form data

    4. patial view page for reusability of html code in products.index.blade.php and partialProductList() in controller

    cut the product listing code from fe.products.index.blade.php

    paste the code into fe.products.partial_productlist.blade.php

    
                            
                              <div calss="col-4">
                                  here is html code for product
                              <div>
                              <div calss="col-4">
                                  here is html code for product
                              <div>
                              <div calss="col-4">
                                  here is html code for product
                              <div>
                                       
                        
                        

    5. include partial page into fe.products.index.blade.php

    1. need id="latest_product_panel" in the products/index.blade for loading ajax data
    2. include the partial page partial_productlist.blade in the products/index.blade
    
                              extends('fe.layouts.master')
                              <div id="latest_product_panel"> 
                                  include('fe.products.partial_productlist')
                              </div>  
                        

    6. in javascript

    class filter_category, .filter_price, .filter_sorting are used in products/index.blade

    
                        $('body').on("change", ".filter_category, .filter_price, .filter_sorting" , function() {   
                        var formData=$('#filterPanel').serialize();
                        console.log(formData);
    
                                $.ajax({
                                            type: 'GET',
                                            url: "{route('product.ajax')}",
                                            
                                            data:formData,
    
                                            dataType: 'html',
                                            success:function(data){ 
                                                        
                                                $('#latest_product_panel').html(data);
                                            },
                                            error: function(xhr, ajaxOptions, thrownError) { // if error occured
                                                
                                                  
                                            } 
    
                                });
    
                      });
    
    
                      
    $('#latest_product_panel').html(data) will replace the content of container id="latest_product_panel" in the products/incex.blade,php. see step 4

    Another solution to send form data

    
                        var formData = {};
                        var category_id = [];
                        $.each($(".filter_category:checked"), function () {
                          category_id.push($(this).val());
                        })
                      
                        formData['price_sort'] = $('.filter_sorting').val();
                        formData['arr_category_ids']=category_id;
                        formData['price_range']=$('.filter_price:checked').val();
    
                        .... 
                        ..... 
                        $.ajax({
                                            type: 'GET',
                                            url: "{route('product.ajax')}",                                        
                                            data:formData,
    
    
                      

    7. Controller function for ajax route

    We had created a function partialProductList in the controller

    
                          public function partialProductList(Request $request){
                            
                              return view('fe.products.partial_productlist',$data);
                         }
                        
    1. we load the partial view (without master or full layout)
    2. the function return only the listing html code

    8. get data from db

    create ProductRepository in App\Repositories for reusability of query

    
                        namespace App\Repositories;
    
                       
                        use App\Models\Product;
                        use DB;
    
                        class ProductRepository
                        {
    
                            public static function getProducts($request,$perPageItems, $latest=Null)
                            {
                               $products=Product:: get();
                               return $products; 
                            }
    
                        
                        }
                      
                        

    Apply filtering options in the above query

    
                            public static function getProducts($request,$perPageItems, $latest=Null)
                            {
                               $products=Product:: query();
                               //single category id ,use where()
                               if(isset($request->category_id)){
                                  $products=$products->where('category_id', $request->category_id);
                               }
    
                               //array of category ids , use whereIn()
                               if(isset($request->arr_category_ids)){
                                  $products=$products->whereIn('category_id', $request->arr_category_ids);
                               }
    
                               $products=$products->get();
                               return $products; 
                            }
    
                          

    use the ProductRepository in the controller functions productList() and partialProductList()

    
                        public function productList(Request $request){                        
                            
                            $data['product']=App\Repositories\ProductRepository::getProducts($request,21, 1);
    
                            return view('fe.products.index',$data);
                          }
    
                          //for ajax loading with product listing only
                         public function partialProductList(Request $request){
                              $data['product']=App\Repositories\ProductRepository::getProducts($request,21, 1);
                              return view('fe.products.partial_productlist',$data);
                         }
                        

    9. Loop the data in partial view products.partial_productlist.blade

    use first block of html code for looping and remove other duplicate blocks

    
                              foreach($product as $row)
                                <div calss="col-4">
                                    here is html code for product
                                <div>
                              endOfForeach 
                        

    Filter product when click category from menu

    in route

    
                        Route::get('/category/{id}', [ProductController::class,'productCategoryWise'])->name('product.category');
                        

    in controller

    
    
                        public function productCategoryWise(Request $r, $slug)
                        {
                            $category=Master::where('slug',$slug)->first();    
                            $r->request->add(['category_id' => $category->id]);
                            $data['product']=App\Repositories\ProductRepository::getProducts($r,21, 1);
                            return view('fe.products.partial_productlist',$data);
                        }
    
    
                        
    1. get category id from master table using slug
    2. add category->id to request object using $r->request->add()