alex
alex

Reputation: 309

How to keep cheked items checked when searching another one in ion-searchbar?

What I want to achieve is to keep the checked items checked when searching another one in ion-searchbar. I managed to keep the checked items but the icon with check doesn't remain checked. What I want is that after I search to keep all the foods list and the ones checked to look liked checked and not to lose state.

This is how it looks:

When I first check them Search food Search food checked When I clear the search it remains the one checked but not with the icon checked

This is my HTML:

<ion-header class="ion-padding ion-no-border">
  <ion-toolbar>
    <ion-title [hidden]="showSearch">Select Foods</ion-title>
    <ion-buttons slot="start">
      <ion-button [hidden]="showSearch" (click)="onCloseModal()">
        Close
      </ion-button>
    </ion-buttons>
    <ion-buttons slot="end">
      <ion-button [hidden]="!showSearch" (click)="showSearch = !showSearch">
        Close
      </ion-button>
    </ion-buttons>
    <ion-buttons slot="end">
      <ion-button (click)="showSearch = !showSearch">
        <ion-icon
          name="search-outline"
          slot="icon-only"
          [hidden]="showSearch"
        ></ion-icon>
      </ion-button>
    </ion-buttons>

    <ion-searchbar
      [hidden]="!showSearch"
      (ionChange)="onSearchFood($event)"
      class="items-searchbar"
      animated
      placeholder="Search Food"
    ></ion-searchbar>
  </ion-toolbar>
</ion-header>

<ion-content>
  <ion-list *ngFor="let food of foods">
    <ion-item (ionChange)="onCheckbox($event)">
      <ion-label>{{ food.name }}</ion-label>
      <ion-checkbox slot="end" value="{{ food.name }}"> </ion-checkbox>
    </ion-item>
  </ion-list>
  <h5 *ngIf="foods.length === 0">
    Oups, no food found.
  </h5>
</ion-content>

This is my TS

import { Component, OnInit } from "@angular/core";
import { ModalController } from "@ionic/angular";

@Component({
  selector: "app-search-modal",
  templateUrl: "./search-modal.component.html",
  styleUrls: ["./search-modal.component.scss"],
})
export class SearchModalComponent implements OnInit {
  showSearch = false;
  searchQuery = "";
  foods = [
    { name: "Apple" },
    { name: "Cucumber" },
    { name: "Pineapple" },
    { name: "Sugar" },
    { name: "Nuts" },
  ];

  allFoods: Array<{ name: string }> = [];

  tickedFoods: Array<{ name: string }> = [];

  constructor(private modalCtrl: ModalController) {
    this.allFoods = this.foods;
  }

  ngOnInit() {}

  onCloseModal() {
    this.modalCtrl.dismiss();
  }

  onSearchIntolerance(event) {
    this.foods = this.allFoods;
    this.searchQuery = event.detail.value;
    if (this.searchQuery && this.searchQuery.trim() !== "") {
      this.foods = this.foods.filter((term) => {
        return (
          term.name
            .toLowerCase()
            .indexOf(this.searchQuery.trim().toLowerCase()) > -1
        );
      });
    } else if (this.searchQuery === "") {
      this.foods = this.tickedFoods;
    }
  }

  onCheckbox(event) {
    if (event.detail.checked === true) {
      let tickedFoods = event.detail.value;
      this.tickedFoods.push({ name: tickedFoods });
    }
  }
}

Upvotes: 1

Views: 243

Answers (1)

Juhi Singh
Juhi Singh

Reputation: 56

If you intend to keep the checked items available, you can use the checked feature of ion-checkbox and create a function to check if the food is present in the tickedFoods array.

onSearchIntolerance(event) {
    this.intolerances = this.allIntolerances;
    this.searchQuery = event.detail.value;
    if (this.searchQuery && this.searchQuery.trim() !== "") {
      this.intolerances = this.intolerances.filter(term => {
        return (
          term.name
            .toLowerCase()
            .indexOf(this.searchQuery.trim().toLowerCase()) > -1
        );
      });
    } else if (this.searchQuery === "") {
      // resetting the intolarances to show all the intolarances
      this.intolerances = this.allIntolerances
    }
  }

<ion-content>
  <ion-list *ngFor="let food of foods">
    <ion-item (ionChange)="onCheckbox($event)">
      <ion-label>{{ food.name }}</ion-label>
      <ion-checkbox slot="end" value="{{ food.name }}" [checked]="isFoodSelected(food.name)"> </ion-checkbox>
    </ion-item>
  </ion-list>
  <h5 *ngIf="foods.length === 0">
    Oups, no food found.
  </h5>
</ion-content>

And create a method isFoodSelected in your component as:

isFoodSelected(testFood) {
    const tickedFoodNames = this.tickedFoods.map(food=>food.name);
    return tickedFoodNames.includes(testFood);
  }

This will allow you to add a checked attribute to your food items that persist in the list after using the search functionality.

Solution: https://stackblitz.com/edit/ionic-v4-xgsiru

Upvotes: 1

Related Questions