1
votes

Hello I am trying to create an ecommerce page on angular where the products are shown with the checkbox option to filter the products. However I am not able to make the checkbox filter work properly as it is showing all the data. Please help.

Here is my stackblitz link - https://stackblitz.com/edit/angular-checkbox-list

<div class="brand-select">
<div class="brand-name">Select Color</div>
<form>
    <div class="form-check brand-checkbox" *ngFor="let col of colors;let index = index">
        <input class="form-check-input" 
             type="checkbox" 
             value="{{col.id}}" 
             id="{{col.id}}" 
             name="checkbox" 
             [(ngModel)]="col.selected"
             (ngModelChange)="filterProducts()">

          <label class="form-check-label" for="{{col.id}}">
            {{col.productColor}}
          </label>
        </div>
    </form>
</div>

<div *ngFor="let prod of productListShow">
    <div *ngFor="let product of prod.product">
        <h5 class="product-inner-title">{{product.productName}}</h5>
    </div>
</div>

In my component .ts file -

public colors: any[] = [
{
  id: 1,
  productColor: "Black",
  selected: false,
},
{
  id: 2,
  productColor: "Green",
  selected: false,
}
]
constructor(private productservice: ProductService) { }

ngOnInit() {
 this.productList = this.productservice.getProducts();
 this.productListShow = this.productList; 
}

  public filterProducts(): void {
  const filteredProductArray = new Array<any>();
  const activeColors = this.colors.filter(c => c.selected).map(c => c.productColor);
  this.productList.forEach(prod => {
      const filteredSubProducts = prod.product.filter(p => activeColors.includes(p.productColor));
       if(filteredSubProducts.length > 0){
           const clonedProduct = Object.assign({}, prod);
           clonedProduct.product = filteredSubProducts;
           filteredProductArray.push(clonedProduct);
       }
  });
  this.productListShow = filteredProductArray;
  console.log(this.productListShow);
}

I am getting the data for my products from a service ProductService here is the data for the products -

import { Products } from './products';
export const PRODUCTS: Products[] = [
    {
        id: 1,
        productCat:'Jeans',
        product: [
            {
                productId: '1',
                productName: 'Trendy Jeans',
                productColor: 'Green',
            },
            {
                productId: '2',
                productName: 'Black tapered Jeans',
                productColor: 'Black',
            },
        ],
    },
    {
        id: 2,
        productCat:'Shirts',
        product: [
            {
                productId: '1',
                productName: 'Trendy Shirts',
                productColor: 'Green',
            },
            {
                productId: '2',
                productName: 'Black Shirts',
                productColor: 'Black',
            },
        ],
    },
]

So When I check green color, it filters all the green color data, i.e shows the green products both from productCat Jeans and Shirts. I only want to show the green color products for jeans if I am showing only jeans data. Please help.

Here is the stackblitz link again - https://stackblitz.com/edit/angular-checkbox-list

1
so you want to show only 1 data? - Sajeetharan
Yeah!! For eg. In Jeans products, If I check green color, I only want to show Green products for Jeans productCat only, but it is showing for both Jeans and Shirts - Akshay

1 Answers

1
votes

You should always have two HTML separated templates for each product types, i have implemented it for Jeans type in the below example.

 filteredJeans: Products[];
 filteredShirts: Products[];

and in template,

<div class="col-md-10 shop-products">
            <div class="row shop-products-listing">
                <div class="col-md-4" *ngFor="let product of filteredJeans">
                    <div class="sp-list-inner">
                        <figure>
                            <a href="{{product.url}}" target="_blank">
                                <h5 class="product-inner-title">{{product.productName}}</h5>
                            </a>
                        </figure>
                    </div>
                </div>
            </div>
        </div>
        <div class="col-md-10 shop-products">
            <div class="row shop-products-listing">
                <div class="col-md-4" *ngFor="let product of filteredShirts">
                    <div class="sp-list-inner">
                        <figure>
                            <a href="{{product.url}}" target="_blank">
                                <h5 class="product-inner-title">{{product.productName}}</h5>
                            </a>
                        </figure>
                    </div>
                </div>
            </div>
        </div>

STACKBLITZ DEMO