0
votes

Have the below ngx-datatable where I want to have the first row expanded on view load. I have tried to call the toggleExpandRow(this.table.row[0]) on the angular lifecycle hook ngAfterViewChecked and the template is not getting updated with the row expanding. Has anyone accomplished this before with ngx-datatable? The below code does not run and is there for information purposes only.

import {
  Component,
  Input,
  Output,
  EventEmitter,
  OnInit,
  ChangeDetectionStrategy,
  ViewEncapsulation,
  ViewChild
} from '@angular/core';
import { defaultTrackByFn } from '@shared/utils';
import { Datatable } from '@app/stores/dashboard-store/models/datatable.model';
import { DatatableComponent as ngxDatatableComponent } from '@swimlane/ngx-datatable';
import { Observable } from 'rxjs';
import { ActiveToggleService } from '@dashboard/services/ActiveToggle.service';

@Component({
  selector: 'fmsl-datatable',
  templateUrl: './datatable.component.html',
  styleUrls: ['./datatable.component.scss'],
  encapsulation: ViewEncapsulation.None,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class DatatableComponent implements OnInit {
  @Input()
  datatable: Datatable;

  @Input()
  isBorrower: boolean;

  @ViewChild('loanTable')
  table: ngxDatatableComponent;

  @Input()
  showLegend: boolean = true;
  trackByFn: Function = defaultTrackByFn;

  // TODO: Implement Datatable Actions
  actions = ['replace with logic later'];

  isBorrower$: Observable<boolean>;

  constructor(private _toggleService: ActiveToggleService) {}

  ngOnInit() {
    // console.log('table:', this.table)
    // console.log('table row detail', this.table.rowDetail)
    // this.table.rowDetail.expandAllRows();
  }

  ngAfterViewChecked() {
    console.log('table:', this.table)
    console.log('table row detail', this.table.rowDetail)
    console.log('table row:', this.table._rows[0])
    this.table.rowDetail.toggleExpandRow(this.table._rows[0]);
  }

  toggleExpandRow(row) {
    console.log('row toggled', row);
    console.log('row table', this.table);
    this.table.rowDetail.toggleExpandRow(row);
  }

  onDetailToggle(event) {
    // on row detail expand we can do something
  }
  toggleActiveInactive(row) {
    const { uuid, loanStatusTypeName } = row;
    this._toggleService.toggleActiveInactive({ uuid, loanStatusTypeName });
  }
}
<div class="row datatable-row">
  <div class="col">
    <!--mdc-replace datatable-->
    <div [ngClass]="datatable.tableClass">
      <!-- {{ datatable | json }} -->
      <ngx-datatable
        #loanTable
        class="material expandable"
        [rows]="datatable.rows"
        [columnMode]="'flex'"
        rowHeight="auto"
        sortType="single"
        [headerHeight]="42"
        [footerHeight]="0"
        [scrollbarH]="true"
        [footerHeight]="0"
        [loadingIndicator]="datatable.loading"
        [messages]="datatable.messages"
      >
        <ngx-datatable-row-detail [rowHeight]="44" (toggle)="onDetailToggle($event)">
          <ng-template
            let-row="row"
            let-expanded="expanded"
            ngx-datatable-row-detail-template
          >
            <div class="expansion-row" style="padding-left:35px;">
              <mdc-icon class="material-icons" aria-hidden="true">info_outline</mdc-icon>
              <span
                [innerHTML]="row.statusProperties.statusDetail"
                class="datatable__expansion-row-message"
              ></span>
            </div>
          </ng-template>
        </ngx-datatable-row-detail>

        <ngx-datatable-column
          [width]="50"
          [resizeable]="false"
          [sortable]="false"
          [draggable]="false"
          [canAutoResize]="false"
        >
          <ng-template let-row="row" let-expanded="expanded" ngx-datatable-cell-template>
            <a
              href="javascript:void(0)"
              [class.datatable-icon-right]="!expanded"
              [class.datatable-icon-down]="expanded"
              title="Expand/Collapse Row"
              (click)="toggleExpandRow(row)"
            >
            </a>
          </ng-template>
        </ngx-datatable-column>

        <ngx-datatable-column
          *ngFor="let col of datatable.columns; index as i; trackBy: trackByFn"
          [name]="col.name"
          resizeable="false"
          [flexGrow]="col.flex"
          [prop]="col.prop"
          [pipe]="col.pipe"
        >
          <ng-template let-column="column" ngx-datatable-header-template let-expanded="true">
            {{ col.name }}
          </ng-template>
          <ng-template let-row="row" let-value="value" ngx-datatable-cell-template>
            <div class="table-cell justify-content-start" [attr.data-heading]="col.name">
              <span *ngIf="col.isIcon; else progressCell">
                <fmsl-datatable-icon
                  *ngIf="value"
                  [actionRequiredBy]="value"
                  [legend]="datatable.legend"
                  [currentRole]="datatable.currentRole"
                ></fmsl-datatable-icon>
              </span>

              <div *ngIf="col.isActions" class="rowActions">
                <button mdc-button (click)="toggleActiveInactive(row)">
                  Mark {{ row.loanStatusTypeName === 'active' ? 'Inactive' : 'Active' }}
                </button>
              </div>

              <ng-template #progressCell>
                <div *ngIf="col.isProgress; else linkCell" class="progress-container">
                  <mdc-linear-progress
                    class="progress-bar loan-status-progress-bar"
                    [determinate]="true"
                    [progress]="value"
                  ></mdc-linear-progress>
                </div>
              </ng-template>

              <ng-template #linkCell>
                <span *ngIf="col.isLink; else valueCell">
                  <a
                    *ngIf="row.sharePointURL; else internalLink"
                    target="_blank"
                    href="{{ row.sharePointURL }}"
                    >{{ value }}
                  </a>
                  <ng-template #internalLink>
                    <a [routerLink]="['/dashboard/deal', 'loan-request-info', row.uuid]">{{
                      value
                    }}</a>
                  </ng-template>
                </span>
              </ng-template>

              <ng-template #valueCell>
                <span>{{ value }}</span>
              </ng-template>
            </div>
          </ng-template>
        </ngx-datatable-column>
      </ngx-datatable>
    </div>
  </div>
</div>
1

1 Answers

0
votes

There is an open issue https://github.com/swimlane/ngx-datatable/issues/929 while using toggle functions with onInit and afterViewInit hooks.

To call toggle function inside ngAfterViewChecked is not a good idea, as this hook will be called multiple times. And once you get it expanded, you cannot collapse it.

Still there is a dirty workaround to call the toggle function inside AfterViewInit within setTimeout:

@ViewChild(DatatableComponent) private table: DatatableComponent;
constructor(private cdRef: ChangeDetectorRef) {}

setTimeout(() => {
    this.table.rowDetails.toggleExpandedRow(ROW);
    this.cdRef.detectChanges();
}, 1000);