Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 770
Lincoln Kupke Avatar asked Mar 08 '23 13:03

Lincoln Kupke


2 Answers

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

like image 152
0mpurdy Avatar answered Mar 20 '23 15:03

0mpurdy


You can use component methods for this. A pipe would work as well, but here's an example if getting it working using component methods.

Run the following on your fabric sub-array (color, type, etc.) to get a count and a list of different items.

var obj = { };
for (var i = 0, j = this.fabrics[0].colors.length; i < j; i++) {
   obj[this.fabrics[0].colors[i]] = (obj[this.fabrics[0].colors[i]] || 0) + 1;
}

If you run this on your sub-array (fabrics[0].colors, let's say), you will end up with an obj that looks like:

{
  black: 5,
  orange: 2,
  green: 8
}

You can run this in a for loop on your fabrics as well, but the general idea still holds. Once you have the object, you will need to turn it into an array for an ngFor (and an ngModel if preferred).

For an example on how to iterate ngFor on an object check out this plunker.

like image 34
Z. Bagley Avatar answered Mar 20 '23 16:03

Z. Bagley