1
votes

I'm styling a checkbox as a button by placing it inside it's label

<label>
 <input type="checkbox" name="...">
</label>

I need to toggle the parent label's class based on whether the checkbox is checked. Now, this would be easy using [ngClass] and a boolean. The problem is, I'm also looping the elements with an *ngFor directive. This apparently used to work in Angular 1.x.x, but in Angular 2/4/... it adds/removes the class for all elements that are repeated. This could easily be solved by accessing the parent DOM elements classList directly, but this is considered a bad practise in Angular. Is there any Angular way to do this or do I have to change my approach completely?

EDIT: my code EDIT 2: Wrong code, fixed.

  <label *ngFor="let item of object.array" [ngClass]="{'label-active': checked}">
    {{item}}
    <input (click)= "checked = !checked"  type="checkbox" name="..." id="..." class="sr-only">
  </label>
2

2 Answers

2
votes

Maintain a checked state for each item of the array that you iterate over using *ngFor in an array of the same size (this.checked in my example), or as property of the items in the data array this.object.array

export class MyComponent {
  object;

  someMethod() {
    this.object = {};
    this.object.array = someData; // whereever you get that data
    this.checked = new Arrray(this.object.array.length);
    this.checked.fill(false);
  }
}
 <label *ngFor="let item of object.array; let i=index" 
    [class.label-active]="checked[i]">
    {{item}}
    <input (click)= "checked[i] = !checked[i]"  type="checkbox" name="..." id="..." class="sr-only">

    <!-- or -->
    <input [(ngModel)]="checked[i]" type="checkbox" name="..." id="..." class="sr-only">
  </label>
0
votes

example.html

<div *ngFor="let item of object.array; let i = index">
    <div (click)="toggleIdField('toggleId_' + i)" [id]="'toggleId_' + i">
    </div>
</div>

example.ts (MyComponent)

toggleIdField(id) {
    let element = document.getElementById(id) as HTMLElement;
    element.classList.contains('active') ? 
    element.classList.remove('active') : 
    element.classList.add('active')
}

Feel free to adapt it