Get value of a select option and filter list of items


#1

Hi,

I’d like to filter a list of items with the select component. The idea is when I select an option, I check if the value option is among my object property and if it’s true, I display the item.

The problem is I don’t know how to get the values from the selected menu and use it in my .ts file.

Here’s the html.

<ion-select [selectOptions]="selectContext" [(ngModel)]="context">
      <ion-option value="all">All</ion-option>
      <ion-option value="atHome">At home</ion-option>
      <ion-option value="outstide">Outside</ion-option>
    </ion-select>

And here’s the list of items.

this.itemsHome = [
      {
        id: 'A1',
        action: 0,
        points: 0,
        label0: '',
        label25: 'A1L25',
        label50: 'A1L50',
        label75: 'A1L75',
        label100: 'A1L100',
        context: 'atHome',
        link: 'Li1'
      },

{
        id: 'A1',
        action: 0,
        points: 0,
        label0: '',
        label25: 'A1L25',
        label50: 'A1L50',
        label75: 'A1L75',
        label100: 'A1L100',
        context: 'outside',
        link: 'Li1'
      },
];

Thanks for the help.


#2
<ion-select (ionChange)="onContextChange($event)">

onContextChange(ctxt: string): void {
  this.items = this.totalItems.filter(item => item.context === ctxt); 
}

Depending on how you are using the items in the template, you may need to inject a ChangeDetectorRef in your constructor and call its detectChanges() method at the end of onContextChange() in order for the changes to reflect when needed.


#3

Thanks for the answer !

But how to get the value of the option when I select a given option ?


#4
<ion-select [(ngModel)}="context">

…and it can be referenced as this.context in the controller.


#5

I dit that and I think it could work because I see in the console that [hidden] is updated for each element but it doesn’t hide elements. It seems like I should refresh the page. I don’t understand why it’s not display dynamically :

hideElement: boolean = false;
...
 onContextChange(value): void {
    var i = 0;
    for (var i = 0; i < this.items.length; i++) {
      if ((this.items[i]["context"]) == value) {
        console.log(this.items[i]["context"]);
        this.items[i].hideElement = true;
      }
      else {
        this.items[i].hideElement = false;
        console.log("out");
      }
    }
    console.log(this.items[0].hideElement);
    console.log(this.items[1].hideElement);
    console.log(this.items[2].hideElement);
    console.log(this.items[3].hideElement);
    console.log(this.items[4].hideElement);
    console.log(this.items[5].hideElement);
  }

Here’s the list :

<ion-list>
    <ion-item-group reorder="{{flag}}" (ionItemReorder)="reorderItems($event)">
      <ion-item-sliding *ngFor="let item of items" #SlidingItem>
        <ion-item [hidden]="hideElement" (click)="goTo(item)">
          {{item.id}}
          <p>{{item.label}}</p>
          <p>Engagement : {{item.points}}% </p>
        </ion-item>
        <ion-item-options side="right">
          <button ion-button (click)="always(SlidingItem, item)">
         100%
       </button>
          <button ion-button (click)="often(SlidingItem, item)">
         75%
       </button>
          <button ion-button (click)="sometimes(SlidingItem, item)">
         50%
       </button>
          <button ion-button (click)="rarely(SlidingItem, item)">
         25%
       </button>
          <button ion-button (click)="never(SlidingItem, item)">
      0%
    </button>
        </ion-item-options>
      </ion-item-sliding>
    </ion-item-group>

  </ion-list>
this.itemsHome = [
      {
        id: 'A1',
        action: 0,
        points: 0,
        label0: '',
        label25: 'A1L25',
        label50: 'A1L50',
        label75: 'A1L75',
        label100: 'A1L100',
        context: 'atHome',
        category: 'reduceEnergyConsomation',
        link: 'Li1'
      },
      {
        id: 'A2',
        action: 0,
        points: 0,
        label0: '',
        label25: 'A2L25',
        label50: 'A2L50',
        label75: 'A2L75',
        label100: 'A2L100',
        context: 'Outside',
        category: 'reduceEnergyConsomation',
        link: 'Li2'
      },

Here’s the select component :

<div class="select">
    <ion-item>
      <ion-label>Filter</ion-label>
      <ion-select class="no-border" (ionChange)="onContextChange($event.value)" [selectOptions]="selectContext" [(ngModel)]="context">
        <ion-option value="all">All</ion-option>
        <ion-option value="atHome">At home</ion-option>
        <ion-option value="outstide">Outside</ion-option>
      </ion-select>
      <ion-select class="no-border" [selectOptions]="selectCategory" [(ngModel)]="category">
        <ion-option value="all">All</ion-option>
        <ion-option value="reduceWaterConsommation">Reduce water consommation</ion-option>
        <ion-option value="reduceEnergyConsommation">Reduce energy consommation</ion-option>
      </ion-select>
    </ion-item>
  </div>

#6

I don’t understand why you are bothering with all this hideElement stuff. Change the contents of items to reflect only the items you want to be displayed. Much clearer.


#7

Because I’d like to hide the item when I select an option to filter the list. What do you mean by changing the content of items ?


#8

I mean “make the items array contain only the items that should be displayed”. That is what my initial code using Array.filter does. You are iterating over items, so if items contains A, B, and C, those all show up. If you change items to only include A and C, B will vanish automatically.


#9

Ok it almost works, thanks ! I didn’t understand your solution at first sight but it’s more cleaner !
The problem now is if I select an other option, it doesn’t work, my items don’t reappear.

How to reset filter or reinitialize my items ?


#10

Ok, I’ve found it, I reinitialize at the beginning :

constructor(app: App, menu: MenuController, public navCtrl: NavController, private myservice: MyService, public events: Events) {

    this.data = myservice.getItemsHome();
    this.items = myservice.getItemsHome();
    this.totalActionsArray = myservice.getTotalActions();
    this.totalPointsArray = myservice.getTotalPoints();
  }


  onContextChange(value): void {
    if (value == 'all') {
      this.items = this.data;
    }
    else {
      this.items = this.data;
      this.items = this.items.filter(item => item.context === value);
    }
  }

#11

Could be simplified. I hate such generically-named properties as “data” and “items”; try to make your code self-documenting by choosing names that are more descriptive, but that being said:

onContextChange(context: string): void {
  this.items = this.data.filter(item => context === 'all' || item.context === context);
}