Search code examples
angulartypescriptangular2-formsangular2-pipe

Angular2 filtering checkboxes


I have an Angular2 grid that contains an array of Fabrics. These Fabrics have properties such as color or fabric Type. Right now the grid has them all displaying. I need to some how have a series of checkboxes for the color and fabric type with the amount occurring next to it. The grid displays the filtered Fabrics only after a button of apply filter is clicked. However when a checkbox is selected the other checkboxes counts change.

Ex.

enter image description here

Can someone provide some insight as how to best go about this? I have all the data for now. Would I create a pipe or a filtering service, or have a form?

** MODELS **

An ProductConfigurationOption is an overall parent of an option choice. Ex. Fabric is an ConfigurationOption.

A configuration-option-choice is a specific fabric such as Tan Chenille. A individual ConfigurationOptionChoice has many OptionChoiceProperties.

product-configuration-option.ts

import { ProductConfigurationOptionChoice } from './product-configuration-option-choice';
import { IProductConfiguratorOptionChoiceProperties } from '../Interfaces/iproduct-configurator-option-choice-properties';
import { IProductConfigurationOptionChoice } from '../Interfaces/iproduct-configuration-option-choice';
import { IProductConfigurationOption } from '../Interfaces/iproduct-configuration-option';

export class ProductConfigurationOption implements IProductConfigurationOption {
   constructor(
        public ConfiguratorID: number,
        public OptionID: number,
        public OptionName: string,
        public OptionDescription: string,
        public OptionSortOrder: number,
        public SKUPartOrdinal: number,
        public ProductConfigurationOptionChoice: IProductConfigurationOptionChoice[],
        public OptionChoicesProperties: IProductConfiguratorOptionChoiceProperties[]
    ) {

    }
}

product-configuration-option-choice.ts

import { ProductConfiguratorOptionChoiceProperties } from '../Models/product-configurator-option-choice-properties';
import { IProductConfiguratorOptionChoiceProperties } from '../Interfaces/iproduct-configurator-option-choice-properties';
import { IProductConfigurationOptionChoice } from '../Interfaces/iproduct-configuration-option-choice';
export class ProductConfigurationOptionChoice implements IProductConfigurationOptionChoice {
    public OptionChoiceID: number;
    public OptionID: number;
    public OptionValue: string;
    public OptionChoiceName: string;
    public OptionChoiceDescription: string;
    public SKUPart: string;
    public ImageURL: string;

    public SortOrder: number;
    public PriceOffset: number;
    public OptionChoiceProperties: IProductConfiguratorOptionChoiceProperties[];
    constructor( ){

    }

     setOptionChoiceProperties(optionProperties: ProductConfiguratorOptionChoiceProperties[]) {
        this.OptionChoiceProperties = optionProperties;
    }
}

product-configurator-option-choice-properties.ts

import { IProductConfiguratorOptionChoiceProperties } from '../Interfaces/iproduct-configurator-option-choice-properties';
export class ProductConfiguratorOptionChoiceProperties implements IProductConfiguratorOptionChoiceProperties {
      constructor(
        public OptionChoiceId: number,
        public PropertyId: number,
        public Name: string,
        public Value: string
    ) {

    }
}

Currently I am trying to get the OptionChoiceProperties and get the count of them and make them checkboxes. Then trying to figure out how to dynamically change the amounts OptionChoiceProperties when a filter is applied.


Solution

  • You can use a pipe to filter your array of items

    filter pipe

    @Pipe({name: 'fabricType'})
    export class FabricTypePipe implements PipeTransform {
      transform(fabrics: any[], fabricTypes: string[]): any[] {
        if (!fabricTypes || fabricTypes.length === 0) return fabrics;
        return fabrics.filter(fabric => fabricTypes.includes(fabric.type));
      }
    }
    

    template

    <div *ngFor="let colour of fabricColours">
      <input type="checkbox" [(ngModel)]="colour.selected" />{{fabrics | fabricType: types | countColour: colour.name}} {{colour.name}}
    </div>
    
    <div *ngFor="let fabric of fabrics | fabricType: types">{{fabric.name}}</div>
    

    Where types can be static e.g.['weave','phur'], a variable (array) or a method (which returns an array).

    To count the number of items you can use also use a pipe

    count pipe

    @Pipe({name: 'countColour'})
    export class CountColourPipe implements PipeTransform {
      transform(fabrics: any[], colour: string): number {
        if (!fabrics || fabrics.length === 0) return 0;
        return fabrics.reduce((count, fabric) => fabric.colour === colour ? count + 1 : count, 0);
      }
    }
    

    Gif showing the counts changing

    enter image description here

    Live plunker example