How to filter results for range slider with multiple checkbox together in Angular 2?

生来就可爱ヽ(ⅴ<●) 提交于 2021-02-19 07:34:11

问题


I am trying to filter results for the given array "db", there are three filters: price, duration, and category.

I tried using filter() method to filter results.

Here is the link of code which i have tried: https://stackblitz.com/edit/multiple-filters?file=app%2Fapp.component.ts

component.html

<div class="filters">
  <div id="price">
  <h3>Price: {{rangeValues[0] + ' - ' + rangeValues[1]}}</h3>
  <p-slider [(ngModel)]="rangeValues" (click)="handleChange()" [min]="0" 
  [max]="2000" [style]="{'width':'14em'}" [range]="true"></p-slider>
</div>
<hr>
<div id="duration">
    <h3>Duration</h3>
    <li><input type="checkbox" (click)="checkFilter('2 days')"> 2 Days</li>
    <li><input type="checkbox" (click)="checkFilter('6 days')">6 Days</li>
</div>
<hr>
<div id="Theme">
    <h3>Theme</h3>
    <li><input type="checkbox" id="Wild Life" (click)="filterTheme('Wild Life')">Wild Life</li>
    <li><input type="checkbox" id="Romance" (click)="filterTheme('Romance')">Romance</li>
    <li><input type="checkbox" id="Food & Drink" (click)="filterTheme('Food & Drink')">Food & Drink</li>
    <li><input type="checkbox" id="Adventure" (click)="filterTheme('Adventure')">Adventure</li>
 </div>
 <hr>
 </div>

 <div class="results">
    <h3>Results</h3>

    <div *ngFor="let p of package">
    <p>{{p.product_name}}</p>
    </div>
 </div>

component.ts

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
 db=[
{
  "id":"1",
  "product_name":"6 Days at Karnataka",
  "price":324,
  "duration":"6 days",
  "category":["Romance"]
},
{
  "id":"5",
  "product_name":"2 Days at Thailand",
  "price":234,
  "duration":"2 days",
  "category":["Romance","Wild Life"]
},
{
  "id":"8",
  "product_name":"2 Days at Delhi",
  "price":1400,
  "duration":"2 days",
  "category": ["Romance","Food & Drink","Adventure"],
}
];
rangeValues: number[] = [0,2000];
package:any;
filterData=[];


ngOnInit(){
  this.packageList();
}

packageList(){
 for(let i = 0; i < this.db.length; i++){
  this.filterData.push(this.db[i]);
  this.package =this.filterData;
 }    
}

handleChange() {
        for(let i = 0; i < this.filterData.length; i++){             
          this.package= this.filterData.filter(item => item.price >=this.rangeValues[0] && item.price <=this.rangeValues[1]);
   }
}

checkFilter(id){ 
    if(id.checked==true){
      for(let i = 0; i < this.filterData.length; i++){
         this.filterData= this.filterData.filter(item => item.duration !== id && item.price >=this.rangeValues[0] && item.price <=this.rangeValues[1]);
          this.package=this.filterData;
      }
    }
    else {
      for(let i = 0; i < this.filterData.length; i++){
          this.filterData= this.filterData.filter(item => item.duration == id && item.price >=this.rangeValues[0] && item.price <=this.rangeValues[1]);
          this.package=this.filterData;
      }
    }
 }


filterTheme(id){
    let b=(<HTMLInputElement>document.getElementById(id));
    if(b.checked==true){
      for(let i = 0; i < this.filterData.length; i++){
        for(let j=0;j< this.filterData[i].category.length; j++){
          if(this.filterData[i].category[j]==id &&  this.filterData[i].price >=this.rangeValues[0] &&  this.filterData[i].price <=this.rangeValues[1]){

            this.package= this.filterData.filter(item => item.category[j]==id && item.price >=this.rangeValues[0] && item.price <=this.rangeValues[1]);
          }
        }
      }
    }else {
      for(let i = 0; i < this.filterData.length; i++){
        for(let j=0;j<this.filterData[i].category.length; j++){
          if(this.filterData[i].category[j]!==id && this.filterData[i].price >=this.rangeValues[0] && this.filterData[i].price <=this.rangeValues[1]){
            this.package = this.filterData.filter(item => item.category[j]!== id && item.price >=this.rangeValues[0] && item.price <=this.rangeValues[1]);

          }
        }
      }
    }

 }

}

What I want to achieve:

  1. price filter: which I have used the range slider to filter results and it filters price correctly but it should also filter results for selected duration and category.

  2. Duration filter: used the checkbox to filter results, this should filter results for the given price and selected category.

  3. Category filter: one product_name can have one or more category and it should filter results for the selected one and price chosen.


回答1:


Well, you are complicating the things by looping over it and checking it you can have one function that would do the work for you.

step1: Take 3 models

rangeValues: number[] = [0, 2000];
  durations: any = [];
  themes: any = [];

step2: assign the values of the user in these models

  handleChange() {
    this.ApplyFilters();
  }

  checkFilter(id) {
    if (this.durations.some(a => a === id)) {
      this.durations = this.durations.filter(a => a !== id)
    } else {
      this.durations.push(id)
    }
    this.ApplyFilters();
  }


  filterTheme(id) {
    if (this.themes.some(a => a === id)) {
      this.themes = this.themes.filter(a => a !== id)
    } else {
      this.themes.push(id)
    }
    this.ApplyFilters();
  }

step3: Create one common filter

  ApplyFilters() {
    this.package = this.filterData.filter(item => {
      return (item.price >= this.rangeValues[0] && item.price <= this.rangeValues[1]) && (this.durations.some(b => b === item.duration) || this.durations.length === 0) && (item.category.every(c => this.themes.some(d => d === c)) || this.themes.length === 0)
    });
  }

And your are done

Here is the demo



来源:https://stackoverflow.com/questions/53994077/how-to-filter-results-for-range-slider-with-multiple-checkbox-together-in-angula

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!