Filter data between ranges

Viewed 90

I want to filter data based on drop down of the range of price example first drop down should be:- $15 so that filter data should be lower or equal to $15 and drop down should show $15. If second is $15-$50 then how I show data in drop down $15-$50 and filter accordingly. What I tried is here but couldn't get what I want. Here is what I tried and still trying to get the desired result, Hope someone could help me.

.html file is

<form [formGroup]="myForm">
 <select name="Price" formControlName="filterProduct">
   <option *ngFor="let k of PriceFilter  | groupBy: 'Value' | keyvalue">
  <div>
   <ng-container *ngFor= "let i of k['value']">
    <span>{{i['DisplayText']}}</span>
   </ng-container>
  </div>
  </option>
 </select>
</form>

and here is my component

PriceFilter = [
{
  "TagId": 20,
  "Type": "Budget",
  "Value": 5,
  "Values": null,
  "DisplayText": "$50",
  "Order": null
},
{
  "TagId": 20,
  "Type": "Budget",
  "Value": 15,
  "Values": null,
  "DisplayText": "$15",
  "Order": null
}]

Stores = [
{
  "Products": [
    {
    "ProductId": 206419,
    "Price": 39.99,
    "PriceLabel": "$39.99",
    "ProductTags": [1,2]
    },
    {
    "ProductId": 206419,
    "Price": 3.99,
    "PriceLabel": "$9.99",
    "ProductTags": [1,2]
    }
 ]}] // can add more fake data to it for testing

constructor(private fb: FormBuilder) { 
  this.myForm = this.fb.group({
    filterProduct: ['']
  })
}

ngOnInit() {
  this.myForm.get('filterProduct').valueChanges.subscribe(
    value => {
      this.Stores.forEach(x => {
        console.log(x.Products.filter(val => value.slice(1) >= 
  val['Price']))
      })
     //  this.Products.filter(val => value.slice(1) <= val['Price'])
    }
  )
}
2 Answers

I have modified your code a bit to accommodate logic for the use case you want. Also I am assuming this that your PriceFilter is configurable so that we can take advantage of it.

First of all you need to have PriceFilter modified to include minValue which you will need to compare store results.

Here is a working example: https://stackblitz.com/edit/angular-ymdwpp?file=src%2Fapp%2Fapp.component.ts

Changes are as follows:

//PriceFilter object
  PriceFilter = [
    {
      "TagId": 20,
      "Type": "Budget",
      "maxValue": 15,
      "minValue": 0,
      "Values": null,
      "DisplayText": "$15",
      "Order": null
    }, {
      "TagId": 20,
      "Type": "Budget",
      "maxValue": 50,
      "minValue": 15,
      "Values": null,
      "DisplayText": "$15-$50",
      "Order": null
    }
  ]

//app.component.ts
  ngOnInit() {

  }

  onChange(index) {
    const filter = this.PriceFilter[index];
    this.Stores.forEach(x => {
      console.log(x.Products.filter(val => (filter.maxValue >= val['Price'] && filter.minValue < val['Price'])))
    })
  }

//app.component.html
<hello name="{{ name }}"></hello>
<p>
    open the console to see the result
</p>

<form [formGroup]="myForm">
    <select name="Price" formControlName="filterProduct" (change)="onChange($event.target.value)">
    <option *ngFor="let k of PriceFilter  | groupBy: 'maxValue' | keyvalue; let ind = index" [value]="ind">
      <div>
   <ng-container *ngFor= "let i of k['value']">
      <span>{{i['DisplayText']}}</span>
   </ng-container>
   </div>
    </option>
    </select>
</form>
<!-- Modify according to your need -->

Take a look and let me know if this helps.

For option value, you can set the lower and upper based on the index of the option. And then filter out, based on that.

The getValue method is meant to do just that. And this is the same object, that you'll receive as value for the valueChanges Observable. You can then do your filtering based on the lower and upper.

Try this:

<form [formGroup]="myForm">
    <select name="Price" formControlName="filterProduct">
    <option *ngFor="let k of PriceFilter; let i = index;"
      [ngValue]="getValue(i)">
      {{ getValue(i).displayText }}
    </option>
  </select>
</form>

<div>
  <ul>
    <li *ngFor= "let product of filteredProducts">
      {{ product | json }}
    </li>
  </ul>
</div>

And in your Component Class:

import { Component } from '@angular/core';
import { FormGroup, FormBuilder, FormControl } from '@angular/forms';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  name = 'Angular';
  myForm: FormGroup;
  filteredProducts = [];
  PriceFilter = [{
      "TagId": 20,
      "Type": "Budget",
      "Value": 15,
      "Values": null,
      "DisplayText": "$15",
      "Order": null
    },
    {
      "TagId": 20,
      "Type": "Budget",
      "Value": 25,
      "Values": null,
      "DisplayText": "$25",
      "Order": null
    },
    {
      "TagId": 20,
      "Type": "Budget",
      "Value": 50,
      "Values": null,
      "DisplayText": "$50",
      "Order": null
    }
  ]

  Stores = [{
    "Products": [{
        "ProductId": 206419,
        "Price": 39.99,
        "PriceLabel": "$39.99",
        "ProductTags": [1, 2]
      },
      {
        "ProductId": 206419,
        "Price": 15.99,
        "PriceLabel": "$15.99",
        "ProductTags": [1, 2]
      },
      {
        "ProductId": 206419,
        "Price": 10.99,
        "PriceLabel": "$10.99",
        "ProductTags": [1, 2]
      },
      {
        "ProductId": 206419,
        "Price": 55.99,
        "PriceLabel": "$55.99",
        "ProductTags": [1, 2]
      },
      {
        "ProductId": 206419,
        "Price": 1.99,
        "PriceLabel": "$1.99",
        "ProductTags": [1, 2]
      },
      {
        "ProductId": 206419,
        "Price": 3.99,
        "PriceLabel": "$9.99",
        "ProductTags": [1, 2]
      }
    ]
  }]

  constructor(private fb: FormBuilder) {
    this.myForm = this.fb.group({
      filterProduct: ['']
    })
  }

  getValue(index) {
    if (index === 0)
      return {
        lower: 0,
        displayText: this.PriceFilter[index].DisplayText,
        upper: this.PriceFilter[index].Value
      };
    else {
      return {
        lower: this.PriceFilter[index - 1].Value,
        upper: this.PriceFilter[index].Value,
        displayText: `${this.PriceFilter[index - 1].DisplayText} - ${this.PriceFilter[index].DisplayText}`
      };
    }
  }

  ngOnInit() {
    this.filteredProducts = [...this.Stores[0].Products];

    this.myForm.get('filterProduct').valueChanges.subscribe(
      value => {
        console.log(value);
        this.filteredProducts = [...this.Stores[0].Products.filter(product => product.Price >= value.lower && product.Price <= value.upper)]
      }
    )
  }
}

Here's a Sample StackBlitz for your ref.

Related