0

I use ngx-datatable a lot in my app and I would like to have some generic template for the column and their respective header.

For now I have

<ngx-datatable #myTable
        XXX>
   <ngx-datatable-column
       name="selection">
       <ng-template let-column="column" ngx-datatable-header-template>
           <app-component-header-table></app-component-header-table>
       </ng-template>
       <ng-template let-row="row" ngx-datatable-cell-template>
           <app-component-content-table></app-component-header-table>
       </ng-template>
  </ngx-datatable-column>
.... rest of the table ...
</ngx-datatable>

What i would like to achieve is to have the component that contains the content and the one that contains the header in a single file/component

And use it more or less like that :

<ngx-datatable #myTable
        XXX>
   <ngx-datatable-column
       name="selection">
       <app-custom-column></app-custom-column>
  </ngx-datatable-column>
.... rest of the table ...
</ngx-datatable>

With obviously the possibility to access the objects column and row inside

1 Answer 1

1

A lot of time wasted in searching better way to avoid copypast in ngx-datatable. There is my solution:

  1. Create new component-handler, i call them - "custom-table".
  2. Provide to this component rows and cols @inputs
  3. Listen changes cols and rewrite columns property.
  4. Declare ViewChild with your custom table cell.

custom-table.ts

export class CustomTableComponent implements OnInit, OnChanges {
  columns = [];

  @ViewChild('table', { static: false }) table: any;
  @ViewChild('primary', { static: true }) primary: TemplateRef<any>;
  @ViewChild('withAvatar', { static: true }) withAvatar: TemplateRef<any>;

  @Input() rows: Array<any>;
  @Input() cols: Array<Object>;

  public selected: TableColumnModelExtended[] = [];

  ngOnChanges(changes: SimpleChanges): void {
    if (changes.hasOwnProperty('cols') && changes.cols.currentValue) {
      this.updateCols();
    }
  }

  ngOnInit() {
    if (this.cols) {
      this.updateCols();
    }
  }

  updateCols(): void {
    this.columns = this.cols.map((col: TableColumnModelExtended) => ({
      ...col,
      cellTemplate: this[col.cellTemplate],
      headerTemplate: this[col.headerTemplate],
    }));
  }
}

custom-table.html

<div class="custom-table">
  <ngx-datatable
    #table
    columnMode="force"
    [rows]="rows"
    [columns]="columns">
  </ngx-datatable>

  <!--COLUMN WITH AVATAR-->
  <ng-template #withAvatar let-value="value" let-row="row">
    <column-with-avatar [value]="value"></column-with-avatar>
  </ng-template>


  <!--PRIMARY COLUMN-->
  <ng-template #primary let-value="value" let-row="row" let-column="column">
    <column-primary [value]="value" [column]="column"></column-primary>
  </ng-template>

</div>

After that you can use it like this.

example-component.ts

export class ExampleComponent {
  public columns: TableColumnModel[] = ExampleListColumns;
  readonly valueList$: BehaviorSubject<DeliveryNote[]> = new BehaviorSubject([]);

}

example-component.html

<custom-table
  [rows]="valueList$ | async"
  [cols]="columns">
</custom-table>

example-component-table.config.ts

export const ExampleListColumns: TableColumnModelExtended[] = [
  {
    cellTemplate: 'primary',
    name: 'Quantity',
    prop: 'quantity',
    cellClass: 'right',
  },
  {
    cellTemplate: 'withAvatar',
    name: 'Avatar',
    prop: 'userAvatar',
  }
];

Be careful with defining column config. You should not to use extra ',' after end of array.

At the end, you get a table that uses the config to display components, and does not repeat the html code over and over.

To add a new column type, you just need to describe it once inside the component and create a @ViewChild inside the component.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.