Ionic

Ionic 5 Product Filter Page

Share your learning

Hey buddy, This is part 2 of ionic 5 shopping app and we will create a product filter page here.

As we have already created a product listing and cart page in the last tutorial, let’s build a product filter page.

Live Demo

Create ionic 5 product filter page

Run the following command to generate the product filter page.

ionic g page pages/product-filter
import { Component, OnInit } from '@angular/core';
import { ModalController, NavParams } from '@ionic/angular';
import { ProductsService } from 'src/app/services/products/products.service';

@Component({
  selector: 'app-product-filter',
  templateUrl: './product-filter.page.html',
  styleUrls: ['./product-filter.page.scss'],
})
export class ProductFilterPage implements OnInit {

  tabs = {
    categories: true,
    price: false
  }

  constructor(
    private modalCtrl: ModalController,
    public productService: ProductsService
  ) {
  
  }

  ngOnInit() {
  }

  dismiss() {
    this.modalCtrl.dismiss();
  }

  price_input() {
    this.productService.priceRange.applied = true;
  }

  price_range(event) {
    let range = event.detail.value;
    this.productService.priceRange.lower = range.lower;
    this.productService.priceRange.upper = range.upper;
    this.productService.priceRange.applied = true;
  }

  selectFilter(type: string) {
    Object.keys(this.tabs).forEach((value, index)=>{
      console.log('object :>> ', value, index);
      this.tabs[value] = false;
    })

    this.tabs[type] = true;
  }

  setFilter(i: number, type: string) {
    console.log('setFilter :>> ', i, type);

    if ('undefined' === typeof this.productService[type][i]['isChecked']) {
      this.productService[type][i]['isChecked'] = false;
    }

    this.productService[type][i]['isChecked'] = !this.productService[type][i]['isChecked'];
  } 

  applyFilter(){
    this.productService.selectedCategories = this.productService.categories.filter(val => val.isChecked);
    this.productService.applyFilter();
    this.modalCtrl.dismiss(true);
  }

  clearFilter() {
    this.productService.uncheckFilters();
    this.productService.applyFilter();
    this.modalCtrl.dismiss(true);
  }

}

We are using price range and product category to filter our products. You can see a product filter icon below the slider in the right corner. When the user clicks on it, it will open the filter page.

On the filter page users can apply category and price range filters. When the user clicks on the apply filter button, it will assign the selected categories to the product service selectedCategories variable. 

Then it will call the applyFilter method from the product service page where it will match all filters with available products. Once all filters are satisfied it will update the products and therefore it will update the product listing page with filtered products.

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class ProductsService {

  selectedCategories: any = [];

  priceRange: PriceRange = {
    lower: 0,
    upper: 100,
    applied: false
  };

  filterItems: any = [];

  cartCount: number = 0;

  listBy: ListBy = {
    nav: false,
    search: false,
    banner: false,
    details: false
  };

  show_result_size: boolean = true;

  bannerImages = [
    {
      imgurl: 'assets/images/slide1.jpg'
    }, {
      imgurl: 'assets/images/slide2.jpg'
    }, {
      imgurl: 'assets/images/slide3.jpg'
    }
  ];

  products = [
    {
      id : 1,
      imgurl: 'assets/images/slide1.jpg',
      name: 'Multi color bags',
      category: 'shopping',
      price: 67,
      totalStock: 10
    }, {
      id : 2,
      imgurl: 'assets/images/slide3.jpg',
      name: 'Daily use bags',
      category: 'routine',
      price: 37,
      totalStock: 10
    }, {
      id : 3,
      imgurl: 'assets/images/slide2.jpg',
      name: 'Real Value',
      category: 'folk',
      price: 77,
      totalStock: 10
    }, {
      id : 4,
      imgurl: 'assets/images/slide1.jpg',
      name: 'Vosto bags',
      category: 'shopping',
      price: 65,
      totalStock: 10
    }
  ];

  categories : any = [
    {
      category : 'shopping'
    }, {
      category : 'folk'
    }, {
      category : 'routine'
    }
  ];

  constructor(
  ) { 
    
  }

  initProductList() {
    this.filterItems = this.products;
    this.showResultCount();
  }

  applyFilter() {
    console.log(this.selectedCategories, this.priceRange);
    if ( this.selectedCategories.length > 0 || this.priceRange.applied ) {
      console.log('Filter applied :>> ');
      this.products = [];

      for(let i = 0; i < this.filterItems.length; i++) {
        let foundCategory = true, foundPrice = true;

        if ( this.selectedCategories.length > 0 ) {
          foundCategory = this.selectedCategories.some( val => val.category.toLocaleLowerCase() === this.filterItems[i]['category'].toLocaleLowerCase() && val.isChecked);
        }
        
        if ( this.priceRange.applied ) {
          let price = this.filterItems[i]['price'];
          foundPrice = ( price >= this.priceRange.lower && price <= this.priceRange.upper );
        }
        
        if(foundCategory && foundPrice) {
          this.products.push(this.filterItems[i]);
        }
        
      }
    } else {
      console.log('No Filter found:>> ');
      this.products = this.filterItems;
    }
  } 


  showResultCount() {
    this.show_result_size = true;
    setTimeout(() => {
      this.show_result_size = false;
    }, 2000);
  }

  resetItems() {
    this.products = [];
    this.filterItems = [];

    this.uncheckFilters();
    this.defaultListBy();
  } 

  uncheckFilters() {
    this.selectedCategories = []
    this.defaultPriceRange();

    for( let i = 0; i < this.categories.length; i++) {
      this.categories[i].isChecked = false;
    }
  }

  defaultPriceRange() {
    this.priceRange = {
      applied:  false,
      lower : 0,
      upper : 100
    }
    
  }

  defaultListBy() {
    Object.keys(this.listBy).forEach(key => {
      this.listBy[key] = false;
    })
  }

}

interface PriceRange {
  lower: any,
  upper: any,
  applied: boolean
}

interface ListBy {
  search: boolean,
  banner: boolean,
  nav: boolean,
  details: boolean
}

If a user clears the filters from the filter page, our product service simply restores all products.

Cheers,

See you in the next learning journey.

Satpal

Recent Posts

How to Switch PHP Versions in XAMPP Easily: Managing Multiple PHP Versions on Ubuntu

Today we are going to learn about managing multiple PHP versions on ubuntu with xampp.…

2 years ago

How to Use Coding to Improve Your Website’s SEO Ranking?

Let's understand about how to use coding to improve your website's SEO. In today’s computerized…

2 years ago

Most Important Linux Commands for Web Developers

Let's understand the most important linux commands for web developers. Linux, as an open-source and…

2 years ago

Top 75+ Laravel Interview Questions Asked by Top MNCs

Today we are going to discuss top 75+ Laravel interview questions asked by top MNCs.Laravel,…

2 years ago

Mailtrap Integration for Email Testing with Laravel 10

Today we will discuss about the Mailtrap integration with laravel 10 .Sending and receiving emails…

2 years ago

Firebase Cloud Messaging (FCM) with Ionic 6: Push Notifications

Today we are going to integrate FCM (Firebase Cloud Messaging) push notifications with ionic application.Firebase…

2 years ago