Home > Software engineering >  Ionic select list of cards
Ionic select list of cards

Time:04-28

I'm trying to select a list of categories on clicking. When I click, the background color must change and if I click another time on the same, the background must return to default color. I need to be able to have a list of all categories if I have not select any categories OR have a list of selected categories

My code for now work like this: if I click on card, the background color change to PINK and if I click another time, it does not change and I can only select one item

page.html

  <ion-grid>
    <ion-row>
        <ion-card
        *ngFor="let tag of tags; index as i;"
        [ngClass]="{ 'use-pink-background': currentSelected == i}"
        (click)="handleClick(i, tag.id)">
          <ion-card-header >
            <ion-item lines="none">
              <p>{{ tag.name_it }}</p>
              <span>{{ tag.id }}</span>
            </ion-item>
          </ion-card-header>
        </ion-card>
    </ion-row>
  </ion-grid>

page.scss

.use-pink-background{
    --ion-background-color: pink;
  }

page.ts

  constructor(private _mysrvTags: TagsService) { }

  ngOnInit() {
    this.loadTags();
  }

   loadTags(){
    this._mysrvTags.getTags().subscribe({
      next: (data:any)=>{
        this.tags = data.taglist
      }
    })
  }


  public currentSelected: Number = null;
  handleClick(i, tag) {
      this.currentSelected = i;
  }

I want to make something like this: enter image description here

CodePudding user response:

The issue has to do with the logic in your ngClass.

You are testing simply for a single value when your question states that you wish to have multiple items.

Your logic inside handleClick is also incorrect in that you set a value to true but never set it to false. This is why you can select once but cannot deselect.

Your question doesn't really have anything to do with the Ionic framework but is a logic question.

So in the interest of time and for the sake of clarity, I have broken it down to a working solution found here at stackblitz.

App component:

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {

  tags=[{
    name_it: 'foo1',
    id: 'foo1',
  },
  {
    name_it: 'foo2',
    id: 'foo2',
  },
  {
    name_it: 'foo3',
    id: 'foo3',
  }];

  currentSelected = new Array(this.tags.length);

  handleClick(index: number, id: string) {
   // the double bang evaluates null/undefined to falsey
   // so you get the initial value set
   // the third bang correctly toggles the value
   this.currentSelected[index] = !!!this.currentSelected[index];
   console.log('tags', this.currentSelected);
  }
}

app.html

<div *ngFor="let tag of tags; index as i;"
[ngClass]="{ 'use-pink-background': currentSelected[i]}"
(click)="handleClick(i, tag.id)">
{{tag.name_it}}
</div>

app.css

.use-pink-background{
  background-color: pink;
}

Below is the same implemented in your code but untested: page.html

<ion-grid>
    <ion-row>
        <ion-card
        *ngFor="let tag of tags; index as i;"
        [ngClass]="{ 'use-pink-background': currentSelected[i] == i}"
        (click)="handleClick(i, tag.id)">
          <ion-card-header >
            <ion-item lines="none">
              <p>{{ tag.name_it }}</p>
              <span>{{ tag.id }}</span>
            </ion-item>
          </ion-card-header>
        </ion-card>
    </ion-row>
  </ion-grid>

page.ts

constructor(private _mysrvTags: TagsService) { }

  currentSelected = [];

  ngOnInit() {
    this.loadTags();
  }

   loadTags(){
    this._mysrvTags.getTags().subscribe({
      next: (data:any)=>{
        this.tags = data.taglist;
        this.currentSelected = new Array(tags.length);
      }
    })
  }


  public currentSelected: Number = null;
  handleClick(i, tag) {
      // double bang will evaluate null/undefined to falsey
      // so the boolean will initialize itself for free
      // then the third bang toggles the boolean correctly
      this.currentSelected[i] = !!!this.currentSelect[i];
  }
  • Related