carreankush
carreankush

Reputation: 651

How to disable all buttons coming from ngFor except the button which has been clicked in angular 8

Please open it in full browser https://stackblitz.com/edit/angular-skzgno?file=src%2Fapp%2Fapp.component.html , Then click button/image of any li tag,The button will be change to different image as like active .Even if you refresh also this active will not be change since we are adding active=true into localstorage.Now the problem is,on page load when you click button of any li,except that button,buttons of other li should be disable and when we refresh also nothing will be change until you clear localstorage.Please find the code below

app.component.html

    <hello name="{{ name }}"></hello>
    <p>
      Start editing to see some magic happen :)
    </p>
    <div>
        <pre>

      </pre>
        <ul>
    <li *ngFor="let item of statusdata">
      <span>{{item.id}}</span>
      <span>{{item.name}}</span>
      <button style="margin-left:10px" (click)="toggleActive(item, !item.active)">
        <img style="width:50px;margin-left:10px" *ngIf="!item?.active || item?.active === false" src ="https://dummyimage.com/qvga" />
        <img style="width:50px;margin-left:10px" style="width:50px;margin-left:10px" *ngIf="item?.active === true" src ="https://dummyimage.com/300.png/09f/fff" />
      </button>
    </li>
        </ul>
    </div>

app.component.ts

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

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

  ngOnInit() {
    this.statusdata = [
      { id: 1, name: "Angular 2" },
      { id: 2, name: "Angular 4" },
      { id: 3, name: "Angular 5" },
      { id: 4, name: "Angular 6" },
      { id: 5, name: "Angular 7" }
    ];

    this.statusdata.forEach(item => {
      this.getCacheItemStatus(item);
    });
  }

  toggleActive(item, activeStatus = true) {
    if(!this.statusdata.some(d => d.active)){
    item.active = activeStatus;
    localStorage.setItem(`item:${item.id}`, JSON.stringify(item));
    }
  }

  getCacheItemStatus(item) {
    const cachedItem = localStorage.getItem(`item:${item.id}`);
    if (cachedItem) {
      const parse = JSON.parse(cachedItem); // Parse cached version
      item.active = parse.active; // If the cached storage item is active
    }
  }
}

Upvotes: 0

Views: 1092

Answers (2)

Emeka Elo
Emeka Elo

Reputation: 506

I'm so so sorry for not being able to adapt this to the code in the question. I faced this challenge and did not want to forget sharing.

say we have this in the typescript file;

movies: any[] = [
{ name: 'Wakanda', year: 2010, rating: 4.5 },
{ name: 'Super', year: 2000, rating: 5 },
{ name: 'Deli', year: 2002, rating: 3 },
{ name: 'Fury', year: 2020, rating: 4 },
];
isDisabled: boolean = false;

Then this in the HTML...

 <div *ngFor="let movie of movies;index as i">
    <div class="wrapper">
        <button (click)="disableBtn('btn' + i)" [disabled]="isDisabled && isDisabled !== 'btn'+i"
            id=btn{{i}}>Vote</button>
    </div>
</div>

The disableBtn function takes the current button and assigns it to the isDisabled variable then [disabled] attribute checks if isDisabled is truthy and if isDisabled is strictly not equal to the current button. This will be true for all other buttons except the one clicked.

The function disables(toggles it) all other buttons except the one clicked.

disableBtn(btn) {
    if (this.isDisabled === btn) { //also re-enables all the buttons
      this.isDisabled = null;
      return;
    }
    this.isDisabled = btn;
  }

Upvotes: 1

Poul Kruijt
Poul Kruijt

Reputation: 71891

Have you tried the [disabled] property?

<button (click)="toggleActive(item, !item.active)" [disabled]="shouldDisable(item)">
shouldDisable(item): boolean {
  return !item.active && this.statusdata.some((status) => status.active);
}

Upvotes: 0

Related Questions