Search code examples
htmlangulartypescriptngforangular-ng-if

How to create a loop with ngfor that has intermittent toolbar buttons


I have this below.

<div class="btn-toolbar special">
  <button type="button" class="btn mr-2 mb-2" [ngClass]="selectedStyles.includes('bikram') ? 'btn-yb' : 'btn-outline-secondary'" (click)="toggleClass('bikram')">Bikram</button>
  <button type="button" class="btn mr-2 mb-2" [ngClass]="selectedStyles.includes('iyengar') ? 'btn-yb' : 'btn-outline-secondary'" (click)="toggleClass('iyengar')">Iyengar</button>
  <button type="button" class="btn mb-2" [ngClass]="selectedStyles.includes('yin') ? 'btn-yb' : 'btn-outline-secondary'" (click)="toggleClass('yin')">Yin</button>
</div>
<div class="btn-toolbar special">
  <button type="button" class="btn mr-2 mb-2" [ngClass]="selectedStyles.includes('hatha') ? 'btn-yb' : 'btn-outline-secondary'" (click)="toggleClass('hatha')">Hatha</button>
  <button type="button" class="btn mr-2 mb-2" [ngClass]="selectedStyles.includes('kundalini') ? 'btn-yb' : 'btn-outline-secondary'" (click)="toggleClass('kundalini')">Kundalini</button>
  <button type="button" class="btn mb-2" [ngClass]="selectedStyles.includes('vinyasa') ? 'btn-yb' : 'btn-outline-secondary'" (click)="toggleClass('vinyasa')">Vinyasa</button>
</div>
<div class="btn-toolbar special">
  <button type="button" class="btn mr-2 mb-2" [ngClass]="selectedStyles.includes('power') ? 'btn-yb' : 'btn-outline-secondary'" (click)="toggleClass('power')">Power</button>
  <button type="button" class="btn mr-2 mb-2" [ngClass]="selectedStyles.includes('sivananda') ? 'btn-yb' : 'btn-outline-secondary'" (click)="toggleClass('sivananda')">Sivananda</button>
  <button type="button" class="btn mb-2" [ngClass]="selectedStyles.includes('restorative') ? 'btn-yb' : 'btn-outline-secondary'" (click)="toggleClass('restorative')">Restorative</button>
</div>
<div class="btn-toolbar special">
  <button type="button" class="btn mr-2 mb-2" [ngClass]="selectedStyles.includes('prenatal') ? 'btn-yb' : 'btn-outline-secondary'" (click)="toggleClass('prenatal')">Prenatal</button>
  <button type="button" class="btn mr-2 mb-2" [ngClass]="selectedStyles.includes('aerial') ? 'btn-yb' : 'btn-outline-secondary'" (click)="toggleClass('aerial')">Aerial</button>
  <button type="button" class="btn mb-2" [ngClass]="selectedStyles.includes('acro') ? 'btn-yb' : 'btn-outline-secondary'" (click)="toggleClass('acro')">Acro</button>
</div>

but I'm hardcoding in the styles in each button ex. 'vinyasa'

now I have a list of the items and I want to loop through them and construct the same thing (3 buttons in each btn-toolbar), something like this.

<div *ngFor="let style of yogaStyles; let i = index">
  <div *ngFor="let number of [0,1,2,3]" class="btn-toolbar special">
    <button type="button" class="btn mr-2 mb-2" [ngClass]="selectedStyles.includes(style.id) ? 'btn-yb' : 'btn-outline-secondary'" (click)="toggleClass(style.id)">{{style.name}}</button>
  </div>
</div>

But I can't figure out the logic to create the button toolbar for 3 buttons at a time given my list of items 'yogaStyles'

any help would be appreciated


Solution

  • You need two loops, you can use slice pipe

    <div class="btn-toolbar special" *ngFor="let row of [0,1,2]">
        <ng-container *ngFor="let style of yogaStyles
                       |slice:(row*3):(row+1)*3; let i = index">
            <button type="button" class="btn mr-2 mb-2" 
                [ngClass]="selectedStyles.includes(style.id) ? 'btn-yb' : 'btn-outline-secondary'">
               {{style.name}}
             </button>
        </ng-container>
    </div>
    

    Anohter option is used an array of arrays:

    toolsBars=[
    [
      {"id": "bikram","name": "bikram"},
      {"id": "iyengar","name": "iyengar"},
      {"id": "yin","name": "yin"}
    ],
    [
      {"id": "hatha","name": "hatha"},
      {"id": "kundalini","name": "kundalini"},
      {"id": "vinyasa","name": "vinyasa"}
    ],
    ...
    ]
    

    You can create the array "hardcode" or using forEach over the array

      yogaStyles = [
        { id: "bikram", name: "bikram" },
        { id: "iyengar", name: "iyengar" },
        { id: "yin", name: "yin" },
        { id: "hatha", name: "hatha" },
        { id: "kundalini", name: "kundalini" },
        { id: "vinyasa", name: "vinyasa" }
      ];
      toolsBar = []; //<--a new variable
    
      ngOnInit() {
        this.yogaStyles.forEach((x, index) => {
          if (index % 3 == 0) this.toolsBar.push([]);
    
          const items = this.toolsBar[this.toolsBar.length - 1];
          items.push({ id: x.id, name: x.name });
        });
      }