Angular 2 collapsible table not collapsing in full

Issue

I’m trying to create a table with many different addresses and many different values for each address and the data is coming from a mock database. Image here enter image description here

The problem I’m facing now is how to make each button to expand each row with individual values. At the moment when you click on the button it expand and collapse only the first value of the first row.

How do we achieve this functionality in Angular2. Please help?

This is the relevant part of the code. Will be happy to provide more info if need!

<!-- collapseble trigger -->
 <a class="btn btn-sm btnCollapse2" data-toggle="collapse" href="#collapse2" role="button" aria-expanded="false"
  aria-controls="collapse2"></a>

<div class="main-content">
 <div class="row">
<div class="col-md-12 accordion" id="accordionExample">
  <div class="card">
    <div class="card-header card-header-grey" id="headingOne">
      <h3 class="card-title">Property List</h3>
      <span class="card-category">Current readings</span>

      <!-- collapseble trigger 1-->
      <button class="btn btn-sm float-right btnCollapse" type="button" data-toggle="collapse" data-target="#collapseOne"
        aria-expanded="false" aria-controls="collapseOne"><i class="material-icons list">list</i>
        <strong>Collapse List
        </strong> </button>

    </div>

    <div class="card-body">
      <div class="table-responsive">

        <table class="table table-hover">
          <thead class="text-primary">
            <tr>
              <th>Property</th>
              <th *ngIf="showBuildingName || sensorType=='S2'">Temp</th>
              <th *ngIf="showBuildingName || sensorType=='S2'">Humid</th>
              <th *ngIf="showBuildingName || sensorType=='S2'">Light</th>
              <th *ngIf="showBuildingName || sensorType=='S2'">Motion</th>
              <th *ngIf="showBuildingName || sensorType=='S1'">Audio</th>
            </tr>
          </thead>

          <!-- COLLAPSE 1-->
          <tbody>
            <ng-template let-building ngFor [ngForOf]="buildingsList" >

              <div *ngIf="showBuildingName">
                <h3 *ngIf="building.id != -1">
                  <a class="building-row" routerLink="/building/{{building.id}}">{{building.name}}</a>

                </h3>
                <h2 *ngIf="building.id == -1">{{building.name}}</h2>
              </div>

              <!-- COLLAPSE 2-->
              <tr *ngFor="let prop of building.properties; let propertyIndex=index" id="collapseOne"  class="collapse show multi-collapse" aria-labelledby="headingOne" data-parent="#accordionExample">

                <a class="btn btn-sm btnCollapse2" data-toggle="collapse"
                  [href]="'#collapse' + propertyIndex" role="button" aria-expanded="false" aria-controls="collapse2"></a>

                <td>
                  <a routerLink="/property/{{prop.id}}" class="collapse show multi-collapse propName" [id]="'collapse' + propertyIndex">{{prop.name}}</a>
                </td>
                <!-- For now, only temp, humid, light have alerts, so save some time but not getting contextual class for others -->
                <td [title]="cellTtip(prop.messages.temp?.message)" [class]="cellClass(prop.messages.temp?.rag)"><a
                    class="building-row"></a>{{prop.sensorTelemetry?.temp ? prop.sensorTelemetry?.temp : '-'}}</td>
                <td class="fine-cell" [title]="cellTtip(prop.messages.humid?.message)" [class]="cellClass(prop.messages.humid?.rag)">{{prop.sensorTelemetry?.humid
                  ? prop.sensorTelemetry?.humid : '-'}}</td>
                <td *ngIf="showBuildingName || sensorType=='S2'" class="fine-cell" [title]="cellTtip(prop.messages.light?.message)"
                  [class]="cellClass(prop.messages.light?.rag)">{{prop.sensorTelemetry?.light ?
                  prop.sensorTelemetry?.light : '-'}}</td>
                <td *ngIf="showBuildingName || sensorType=='S2'" class="fine-cell">{{prop.sensorTelemetry?.motion
                  >= 0 ? prop.sensorTelemetry?.motion : '-'}}</td>
                <td *ngIf="showBuildingName || sensorType=='S1'" class="fine-cell">{{prop.sensorTelemetry?.audio
                  >=
                  0 ? prop.sensorTelemetry?.audio : '-'}}</td>
              </tr>

            </ng-template>
          </tbody>
        </table>
      </div>
    </div>

  </div>
</div>

here is my coomponent.ts

export class BuildingListComponent implements OnInit {

buildingsList: Building[];
sensorType: string;
@Input() showBuildingName: boolean;

@Input()
set buildings(buildings: Building[]) {

this.buildingsList = _.map(buildings, (building) => {
  const properties = _.map(building.properties, (property) => {

    return {
      ...property,
      name: _.startCase(property.name)
    };
  });
  // properties is array of {property: property, name: property.name}
  properties.sort(this.naturalCompare);

  // in the mode where we are showing only 1 building,
  // restrict columns shown by sensor type
  if (!this.showBuildingName) {
    this.sensorType = properties[0].sensorType;
  }
  return {
    ...building,
    properties
  };
});
}

Solution

Change collapse element id dynamic value at the time click element href. Click element href same value the open collapse id That only open collapse correctly.
for one example:

<div *ngFor="let prop of building.properties; let propertyIndex=index">
<a class="btn btn-sm btnCollapse2" data-toggle="collapse" [href]="'#collapse' + propertyIndex" role="button" aria-expanded="false" aria-controls="collapse2"></a>

<div class="collapse multi-collapse" [id]="'collapse' + propertyIndex"><p>{{prop.name}}</p></div>
</div>

Answered By – Jai Kumaresh

Answer Checked By – Gilberto Lyons (AngularFixing Admin)

Leave a Reply

Your email address will not be published.