Angular2 checkboxes for filtering data

I'm working with an Angular2 grid that showcases an array of Fabrics, each with its own color or fabric type properties. Right now, all Fabrics are displayed in the grid, but I need to implement a series of checkboxes for color and fabric type, along with the corresponding quantity next to each checkbox. The filtered Fabrics should only display after clicking on an "apply filter" button, and selecting one checkbox should dynamically update the counts of the other checkboxes.

For example:

https://i.sstatic.net/tcs25.png

I would appreciate any guidance on how to approach this. I already have all the necessary data. Should I create a pipe, a filtering service, or a form?

** MODELS **

A ProductConfigurationOption serves as the parent option for choice options, such as Fabric being a ConfigurationOption.

A configuration-option-choice represents a specific fabric like Tan Chenille. Each individual ConfigurationOptionChoice comes with various 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, my approach involves extracting OptionChoiceProperties, converting them into checkboxes representing their quantities, and exploring ways to dynamically adjust these quantities when filters are applied.

Answer №1

If you want to narrow down your array of items, consider utilizing a pipe for filtering

filtering items using 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));
  }
}

how to implement in 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>

You can set types as constant like['weave','phur'], dynamic (array), or a function that returns an array.

To calculate the total number of items, a separate pipe can be utilized

counting items with 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);
  }
}

See how the counts change in this animated image

https://i.sstatic.net/JJKpM.gif

Check out a live plunker example

Answer №2

If you want to achieve this, consider using component methods. While a pipe could also work, here's an instance demonstrating how to make it work with component methods.

Execute the code below on your fabric sub-array (such as color, type, etc.) to obtain a count and a list of distinct 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;
}

When run on your sub-array (e.g., fabrics[0].colors), the resulting 'obj' will appear as follows:

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

You can iterate this in a for loop on your fabrics too; the core concept remains unchanged. Once the object is prepared, converting it into an array will be essential for utilizing ngFor (as well as ngModel if desired).

To see an example of iterating ngFor on an object, you can refer to this plunker.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

CSS Styles not being applied globally in Angular

I've been struggling to properly set the Bootstrap downloaded css styles for my Angular project, despite following some instructions provided here: The styles were downloaded from: https://i.sstatic.net/g0kGH.png Initially, I was expecting it to re ...

Exploring the Possibilities of Nipplejs Integration in Vue with Quasar

Trying to implement Nipplejs in my Vue Project using quasar Components. Installed nipplejs through npm install nipplejs --save. Attempted integration of the nipple with the code snippet below: <template> <div id="joystick_zone">&l ...

Understanding the concept of mutable properties in Typescript

Why can the property 'name' in the class 'PersonImpl' be reassigned even though it is not declared as read-only in the Person interface? interface Person { readonly name: string; } interface Greeting extends Person { greet( ...

Should I link my Angular Material 2 data table to AngularFire2 or Firebase service?

Trying to make this work has been quite the struggle. I've spent hours experimenting, but nothing seems to be working as expected. The md data table is relatively new, so there isn't much information available online yet. Connecting Firebase to t ...

Using injected services within static methods may seem tricky at first, but once you

I am exploring the integration of angularjs and typescript in my project. Currently, I am working on creating an Orm factory using typescript but have encountered some challenges. The structure of my factory class is as follows: class OrmModel implements ...

Getting a TypeError following the execution of 'npm update' and 'ng build -prod' commands

Recently, I updated my npm modules and attempted to run ng build -prod, a command that had previously been running smoothly. However, I encountered the following error: TypeError: extractedChunk.getNumberOfModules is not a function at ExtractTextPlugi ...

Typescript compilation fails to include require statements in certain files

Currently, I am in the process of converting a Node.js project to TypeScript. The first two main files of the Node project transpiled correctly, but the third file ran into issues with the requires statement at the top for pulling in dependencies. Despite ...

Adjust the height of a div vertically in Angular 2+

Recently, I started using angular2 and I've been attempting to create a vertically resizable div without success. I have experimented with a directive for this purpose. Below is the code for my directive: import { Directive, HostListener, ElementRef ...

Adding local images to Excel can be easily accomplished using Office Scripts

Hello, I've been attempting to replace Excel cells that contain image filepaths with the actual images themselves. I found an example in Office Scripts that shows how to insert images with online URLs but doesn't mention anything about inserting ...

Utilizing TS2722 alongside restrictive parameters in tsconfig

I have encountered these errors due to the presence of the strictNullChecks parameter, which is activated by the strict configuration in the tsconfig.json file. It appears that when arguments.length === 2, the ab function should be available (thanks to Fun ...

Instructions on opening a modal and changing the source of the iframe within the modal

I currently have a modal within my application that is triggered by Bootstrap: <div class="modal full-page fade" tabindex="-1" role="dialog" id="fullpageModal"> <div class="full-page-content"> <button type="button" class="close" d ...

Angular project is showing a unique error that says '$localize' is undefined according to Eslint

I successfully implemented localization in my Angular 15 project. However, I encountered an issue with linting for .ts files: error '$localize' is not defined no-undef Here's the configuration in my .eslintrc.json file: { "root": true, ...

Steps to activate a function within an angular6 form-related directive

Is there a way to execute a function within a directive when the form is marked as pristine? I want to apply a CSS class to a tab header when the form is pristine. <form [formGroup]="awayForm" (ngSubmit)="onSubmit()" awayConfirm [cancelClicked]="cancel ...

What is the process for including the 'Access-Control-Allow-Origin' header in all responses?

Exploring the world of web development, I have started learning play framework for my backend using play 2.8.x framework and for frontend development, I am utilizing angular 8. However, I have encountered an issue while trying to retrieve a response from t ...

Do I really need to install @angular/router as a dependency in Angular CLI even if I don't plan on using it?

After creating a new Angular CLI project, I noticed that certain dependencies in the package.json file seemed unnecessary. I wanted to remove them along with FormModules and HttpModules from imports: @angular/forms": "^4.0.0", @angular/http": "^4.0.0", @a ...

Exploring the Ways to Determine Array Type in Typescript Generics

I'm working with a method that looks like this: public select(fieldName: keyof TType) In this scenario, TType can potentially be an array type. If fieldName is called with a type of User[], I want to access the properties of User instead of the defa ...

Sample test scenario for a service function that includes an HTTP subscription using Angular's HTTP RxJS

I have a service method that includes an HTTP call and subscribes immediately to the response code in order to execute the rest of the action command based on it. Here is an example of the service method: processData(id): void { const url = `http://l ...

Creating and Injecting Singleton in Angular 2

I have a custom alert directive set up in my Angular app: import { Component } from 'angular2/core'; import { CORE_DIRECTIVES } from 'angular2/common'; import { Alert } from 'ng2-bootstrap/ng2-bootstrap'; @Component({ sele ...

Guide to locating a particular node within an array of nested objects by utilizing the object

Dealing with an array of nested objects, the goal is to compare values with a flat array and update the property matchFound. If the parent's matchFound is true, then all its children should inherit this value. treeData = [{ field: 'make&a ...

The ActivatedRoute.routeConfig object appears to be empty in an Angular 2 project built with Angular-cli

Two projects I've created using angular-cli are working perfectly fine. However, in one of them, the routeConfig is showing as null and I can't figure out what's causing this issue. Both projects have identical package.json files, so there ...