Laravel 11 E-Commerce - Products Filter By Category

Welcome back to the Laravel E-Commerce Tutorial. In this video, we will learn about filtering products by categories.

Step 1: Fetch All Categories

First, let's display all categories on the shop page. Go to the ShopController and inside the index function, fetch all categories:


$categories = Category::orderBy('name','ASC')->get();

Step 2: Return Categories to the View

Return the categories to the shop view.

Step 3: Display Categories on the Shop Page

Go to the shop.blade.php file and display the categories:


<div class="accordion" id="categories-list">
<div class="accordion-item mb-4 pb-3">
<h5 class="accordion-header" id="accordion-heading-1">
<button class="accordion-button p-0 border-0 fs-5 text-uppercase" type="button" data-bs-toggle="collapse" data-bs-target="#accordion-filter-1" aria-expanded="true" aria-controls="accordion-filter-1">
Product Categories
<svg class="accordion-button__icon type2" viewBox="0 0 10 6" xmlns="http://www.w3.org/2000/svg">
<g aria-hidden="true" stroke="none" fill-rule="evenodd">
<path d="M5.35668 0.159286C5.16235 -0.053094 4.83769 -0.0530941 4.64287 0.159286L0.147611 5.05963C-0.0492049 5.27473 -0.049205 5.62357 0.147611 5.83813C0.344427 6.05323 0.664108 6.05323 0.860924 5.83813L5 1.32706L9.13858 5.83867C9.33589 6.05378 9.65507 6.05378 9.85239 5.83867C10.0492 5.62357 10.0492 5.27473 9.85239 5.06018L5.35668 0.159286Z" />
</g>
</svg>
</button>
</h5>
<div id="accordion-filter-1" class="accordion-collapse collapse show border-0" aria-labelledby="accordion-heading-1" data-bs-parent="#categories-list">
<div class="accordion-body px-0 pb-0 pt-3">
<ul class="list list-inline mb-0 category-list">
@foreach ($categories as $category)
<li class="list-item">
<span class="menu-link py-1"> <input type="checkbox" name="categories" value="{{$category->id}}" class="chk-category" @if(in_array($category->id,explode(',',$f_categories))) checked="checked" @endif /> {{$category->name}}</span> <span class="text-right float-right">{{$category->products()->count()}}</span>
</li>
@endforeach
</ul>
</div>
</div>
</div>
</div>

Step 4: Add Hidden Field to the Filter Form

Inside the filter form, add an input hidden field:


<input type="hidden" name="categories" id="hdnCategories" />

Step 5: Bind Checkbox Change Event

Bind the change event to the checkbox:


@push('scripts')
<script>
$(function(){

$("input[name='categories']").on("change",function(){
var categories ="";
$("input[name='categories']:checked").each(function(){
if(categories=="")
{
categories += $(this).val();
}
else{
categories += "," + $(this).val();
}
});
$("#hdnCategories").val(categories);
$("#frmfilter").submit();
});
});
</script>
@endpush

Step 6: Filter Products by Category

Go to the ShopController and inside the index method, create a new variable for assigning the filter category query string value:


$f_categories = $request->query('categories');

Return this $f_categories to the view. Inside the compact, just pass here f_categories. Now, add the where condition:



public function index(Request $request)
{
$size = $request->query('size')?$request->query('size'):12;
$sorting = $request->query('sorting')?$request->query('sorting'):'default';
$f_brands = $request->query('brands');
$f_categories = $request->query('categories');

if($sorting=='date')
{
$products = Product::where(function($query) use ($f_brands){
$query->whereIn('brand_id',explode(',',$f_brands))->orWhereRaw("'".$f_brands."' = ''");
})
->where(function($query) use ($f_categories){
$query->whereIn('category_id',explode(',',$f_categories))->orWhereRaw("'".$f_categories."' = ''");
})
->orderBy('created_at','DESC')->paginate($size);
}
else if($sorting=="price")
{
$products = Product::where(function($query) use ($f_brands){
$query->whereIn('brand_id',explode(',',$f_brands))->orWhereRaw("'".$f_brands."' = ''");
})
->where(function($query) use ($f_categories){
$query->whereIn('category_id',explode(',',$f_categories))->orWhereRaw("'".$f_categories."' = ''");
})
->orderBy('regular_price','ASC')->paginate($size);
}
else if($sorting=="price-desc")
{
$products = Product::where(function($query) use ($f_brands){
$query->whereIn('brand_id',explode(',',$f_brands))->orWhereRaw("'".$f_brands."' = ''");
})
->where(function($query) use ($f_categories){
$query->whereIn('category_id',explode(',',$f_categories))->orWhereRaw("'".$f_categories."' = ''");
})
->orderBy('regular_price','DESC')->paginate($size);
}
else{
$products = Product::where(function($query) use ($f_brands){
$query->whereIn('brand_id',explode(',',$f_brands))->orWhereRaw("'".$f_brands."' = ''");
})
->where(function($query) use ($f_categories){
$query->whereIn('category_id',explode(',',$f_categories))->orWhereRaw("'".$f_categories."' = ''");
})
->paginate($size);
}
$categories = Category::orderBy("name","ASC")->get();
$brands = Brand::orderBy("name","ASC")->get();
return view('shop',compact("products","size","sorting","categories","brands","f_brands","f_categories"));
}

Final Step: Check the Category Filter

Now, let's check the category filter. Switch to the browser and refresh the page. Click on any category, and you can see all the products related to this category. Click on another category, and you can see the products of these categories. You can also see the filtered categories. Now, click on this to remove the category from the filter.

So, in this way, you can filter products by category.

That's all about filtering products by category.