Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Collapse area with a data loop

I have a SPA (single page application) where there is a table that should expand details.

This is the code:

<div class="row mt-4" *ngFor="let row of rows">
    <div class="col-12">
        <button class="btn btn-link" (click)="isCollapsed = !isCollapsed"
          [attr.aria-expanded]="!isCollapsed" aria-controls="collapseExample">
            <i class="fa" aria-hidden="true"></i>
            Details
        </button>
        <div [ngbCollapse]="isCollapsed">
            {{ row.detail}}
        </div>
    </div>
</div>

I can't make it expand just the detail of the clicked column

like image 746
MarceloBoni Avatar asked Dec 07 '22 14:12

MarceloBoni


2 Answers

I solved it this way, which I guess is a little more convenient than actually changing the data itself.

In the HTML section of the component, get the index of your ngFor loop and use this index-variable in the event-binding and the ngbCollapse directive. To make this work, you need an array of booleans property in your component.ts file.

component HTML

<div *ngFor="let row of rows; let i = index">
    <button type="button" (click)="isCollapsed[i] = !isCollapsed[i]">
        Button Text
    </button>
    <div [ngbCollapse]="isCollapsed[i]">
        .. some content ..
    </div>
</div>

component TypeScript

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

  public isCollapsed: boolean[] = [];

}
like image 118
DrackThor Avatar answered Dec 28 '22 07:12

DrackThor


You have a single variable isCollapsed which is controlling the expand/collapse for each div (so either all will be expanded, or all will be collapsed). You haven't posted the Typescript, but I'm assuming it looks like this:

export class MyComponent {

  public isCollapsed: boolean = true;

  public rows: object[] = [
    { detail: 'x' },
    { detail: 'y' }
  ]; 
}

You would need individual isCollapsed variables to keep track of individual divs.

If you have control over the objects in rows you could add it there:

public rows: object[] = [
  {
    detail: 'x',
    isCollapsed: true
  },
  {
    detail: 'y',
    isCollapsed: true
  }
];

Then change the HTML as follows:

<div class="row mt-4" *ngFor="let row of rows">
    <div class="col-12">
        <button class="btn btn-link" (click)="row.isCollapsed = !row.isCollapsed"
          [attr.aria-expanded]="!row.isCollapsed" aria-controls="collapseExample">
            <i class="fa" aria-hidden="true"></i>
            Details
        </button>
        <div [ngbCollapse]="row.isCollapsed">
            {{ row.detail}}
        </div>
    </div>
</div>

This will allow you to have control over expanding/collapsing individual divs. Please see this Plunker for a demo

like image 21
Ian A Avatar answered Dec 28 '22 08:12

Ian A