Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CAN NOT expand Angular Material table

I tried for the past 2 weeks to get this code to work. I searched and tried the solution from Philipp Kief which is a solution that I could partly understand. I'm new.

And I also studied these other solutions. Ho Wei Lip 2 and Ho Wei Lip 3

Unfortunately, I'm stuck and I don't know why the table doesn't expand. I don't get an error, but it seems to (click) and MatRipple seems to respond. I also tried, material expansion panel, but it seems off topic. Could someone point me in the right direction? Thank you.

import { Component, OnInit, ViewChild } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { DataSource } from '@angular/cdk/collections';
import { Incident } from './interface';
import {
  MatSort,
  MatTableDataSource,
  ICON_REGISTRY_PROVIDER,
  MatPaginator
} from '@angular/material';
import {
  animate,
  state,
  style,
  transition,
  trigger
} from '@angular/animations';
import { switchMap, concatMap } from 'rxjs/operators';
import { interval } from 'rxjs';
import { timer } from 'rxjs/observable/timer';

@Component({
  selector: 'app-incident',
  templateUrl: './incident.component.html',
  styleUrls: ['./incident.component.css'],
  animations: [
    trigger('detailExpand', [
      state(
        'collapsed',
        style({ height: '0px', minHeight: '0', visibility: 'hidden' })
      ),
      state('expanded', style({ height: '*', visibility: 'visible' })),
      transition(
        'expanded <=> collapsed',
        animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')
      )
    ])
  ]
})
export class IncidentComponent implements OnInit {
  constructor(private http: HttpClient) {}
  @ViewChild(MatSort) sort: MatSort;
  private serviceUrl = 'http://localhost:3001/api-incidents/55';

  FIVE_MINUTES = 5 * 60 * 1000;
  panelOpenState = false;
  incidents: Incident;
  incidentParseArray: any;
  incidents_sortable: any;
  displayedColumns: string[] = [
    // 'statusIcon',
    'incident'
    // 'INCIDENT_TYPE',
    // 'MODIFICATION_DATE',
    // 'prognosisIcon'
  ];
  dataSource = new MatTableDataSource<Incident>(this.incidentParseArray);

  expandedElement: any;
  isExpansionDetailRow = (i: number, row: Object) =>
    row.hasOwnProperty('detailRow')

  ngOnInit() {
    timer(0, this.FIVE_MINUTES).subscribe(() => {
      this.http.get<Incident>(this.serviceUrl).subscribe(response => {
        this.incidents = response;
        const incidentArray = Object.values(this.incidents);
        // console.log('array ===> ', incidentArray);
        this.incidentParseArray = incidentArray.map(
          ({
            INCIDENT_NAME,
            eStatus,
            eSTATUS_COLOR,
            INCIDENT_TYPE,
            ePROGNOSIS,
            ePROGNOSIS_COLOR,
            MODIFICATION_DATE
          }) => {
            const [incident, aux] = INCIDENT_NAME.split(/-\s+/, 2);
            const [status, active] = eStatus.split(/-\s+/, 2);
            const [junk0, statusColor, junk1] = eSTATUS_COLOR.split(/\./, 3);
            const [junk2, prognosisColor, junk3] = ePROGNOSIS_COLOR.split(
              /\./,
              3
            );
            const statusIcon = assignStatusIcon(statusColor);
            const prognosisIcon = assignPrognosisIcon(ePROGNOSIS);
            const prognosisColorText = assignPrognosisColor(prognosisColor);
            const statusColorText = assignStatusColor(statusColor);

            return {
              incident,
              status,
              statusColor,
              statusIcon,
              statusColorText,
              prognosisColor,
              prognosisColorText,
              INCIDENT_TYPE,
              ePROGNOSIS,
              prognosisIcon,
              MODIFICATION_DATE
            };
          }
        );
      });
    });
  }
}

function assignStatusIcon(color) {
  let icon = '';
  if (color === 'gray') {
    icon = 'brightness_1';
  } else if (color === 'green') {
    icon = 'brightness_1';
  } else {
    icon = 'broken_image';
  }
  return icon;
}

function assignStatusColor(color) {
  let pcolor = '';
  if (color === 'gray') {
    pcolor = 'grey-text';
  } else if (color === 'green') {
    pcolor = '#00c853 green-text accent-4';
  } else {
    pcolor = 'black-text';
  }
  return pcolor;
}

function assignPrognosisIcon(str) {
  let icon = '';
  if (str === 'Monitoring') {
    icon = 'remove_red_eye';
  } else if (str === 'Response') {
    icon = 'directions_walk';
  } else {
    icon = 'broken_image';
  }
  return icon;
}

function assignPrognosisColor(color) {
  let pcolor = '';
  if (color === 'grey') {
    pcolor = 'grey-text';
  } else if (color === 'red') {
    pcolor = 'red-text';
  } else {
    pcolor = 'black-text';
  }
  return pcolor;
}

and this is my template.

<mat-table #table [dataSource]="incidentParseArray" matSort class="z-depth-2 table-font-size
    mat-display-10">
    <ng-container matColumnDef="incident">
        <th mat-header-cell *matHeaderCellDef class="table-font-size" [ngClass]="'customWidthClass'">
            INCIDENT </th>
        <td mat-cell *matCellDef="let element" class="table-font-size mat-cell" [ngClass]="'customWidthClass'">
            {{element.incident}} </td>
    </ng-container>
    <!-- EXPANDED CONTENT  - TEST -->
    <ng-container matColumnDef="expandedDetail">
        <mat-cell *matCellDef="let element">
            The symbol for {{element.INCIDENT_TYPE}} is
            TEST TEST TEST
        </mat-cell>
    </ng-container>

    <mat-row *matRowDef="let row; columns: ['expandedDetail']; when: isExpansionDetailRow"
        [@detailExpand]="row.element == expandedElement ? 'expanded' : 'collapsed'"
        style="overflow: hidden">
    </mat-row>


    <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
    <mat-row mat-row *matRowDef="let row; columns: displayedColumns;"
        matRipple
        class="element-row"
        [class.expanded]="expandedElement == row"
        (click)="expandedElement= row">

    </mat-row>

</mat-table>
like image 428
vt2424253 Avatar asked May 12 '19 18:05

vt2424253


1 Answers

The key to this working is when: isExpansionDetailRow which calls the following function expression... it essentially evaluates each object in the MatTableDataSource for a property of detailRow and returns true if present.

isExpansionDetailRow = (i: number, row: Object) =>
    row.hasOwnProperty('detailRow')

In the following stackblitz notice this block of code, this is essentially taking the original element and concatenating it with a property called detailRow and a redundant copy of the element to be used to render data in the expanded row. (since they are separate and do not use the same data object) rows.push(element, { detailRow: true, element })

export class ExampleDataSource extends DataSource<any> {
  /** Connect function called by the table to retrieve one stream containing the data to render. */
  connect(): Observable<Element[]> {
    const rows = [];
    ELEMENT_DATA.forEach(element => rows.push(element, { detailRow: true, element }));
    console.log(rows);
    return of(rows);
  }

  disconnect() { }
}

Stackblitz

https://stackblitz.com/edit/div-on-click-qqcdmx?embed=1&file=app/table-basic-example.ts


During your incidentArray.map() in the NgOnInit make sure you are adding this property to the rows that you want to be expandable.

like image 85
Marshal Avatar answered Oct 18 '22 06:10

Marshal