0

I'm trying to build a component to display a table with header repeated per each row on small display. I don't know how to repeat the header.

This is what I'd like to obtain:

Desktop:

+-----------------------------------------------------------+
|   Header 1   |   Header 2   |   Header 3   |   Header 4   | 
+-----------------------------------------------------------+
|   field 1-1  |   field 1-2  |   field 1-3  |   field 1-4  |
+-----------------------------------------------------------+
|   field 2-1  |   field 2-2  |   field 2-3  |   field 2-4  |
+-----------------------------------------------------------+
|   field 3-1  |   field 3-2  |   field 3-3  |   field 3-4  |
+-----------------------------------------------------------+

Mobile:

+---------------------+
| Header 1: field 1-1 |
| Header 2: field 1-2 |
| Header 3: field 1-3 |
| Header 4: field 1-4 |
+---------------------+
| Header 1: field 2-1 |
| Header 2: field 2-2 |
| Header 3: field 2-3 |
| Header 4: field 2-4 |
+---------------------+
| Header 1: field 3-1 |
| Header 2: field 3-2 |
| Header 3: field 3-3 |
| Header 4: field 3-4 |
+---------------------+
| Header 1: field 4-1 |
| Header 2: field 4-2 |
| Header 3: field 4-3 |
| Header 4: field 4-4 |
+---------------------+

The markup is:

<my-table [items]="items">
    <my-col>
        <my-label>Header 1</my-label>
        <my-field let-item>{{item.field1}}</my-field>
    </my-col>
    <my-col>
        <my-label>Header 2</my-label>
        <my-field let-item>{{item.field2}}</my-field>
    </my-col>
    <my-col>
        <my-label>Header 3</my-label>
        <my-field let-item>{{item.field3}}</my-field>
    </my-col>
    <my-col>
        <my-label>Header 4</my-label>
        <my-field let-item>{{item.field4}}</my-field>
    </my-col>
</my-table>

Then I defined following components:

@Component({
    selector: 'my-label',
    template: `<ng-template #tpl><ng-content></ng-content></ng-template>`
})
export class MyLabelComponent {
    @ViewChild("tpl") template;
}

@Component({
    selector: 'my-col',
    template: '<ng-content></ng-content>'
})
export class MyTableColumnComponent {
    @Input("class") className: string = "col";
    @ContentChild(MyLabelComponent) label;
}

And then for the table:


@Component({
    selector: 'exa-table2',
    template: `
<div class="my-table">
    <div class="my-head">
        <ng-container *ngFor="let col of columns">
            <div class="{{col-className}}">
                <ng-container *ngTemplateOutlet="col.label.template"></ng-container>
            </div>
        </ng-container>
    </div>
    <div class="my-body">
        <div class="my-row" *ngFor="let item of items">
            <ng-container *ngFor="let col of columns">
                <div class="small {{col-className}}">
                    <ng-container *ngTemplateOutlet="col.label.template"></ng-container>
                </div>
            </ng-container>
        </div>
    </div>
</div>
    `,
    styleUrls: ['./exa-table.component.scss'],
})
export class MyTableComponent {
    @Input() items: any[];

    @ContentChildren(MyTableColumnComponent) columns: QueryList<MyTableColumnComponent>;

}

I'm stucked now because I'm not able to repeat on each row. As far as I understood it's not possible to clone a templateRef (https://stackoverflow.com/a/50080838/10226165), and only the last 'copy' will be shown.

Do you have any idea on how I can proceed?

tan tuffah
  • 11
  • 4

1 Answers1

0

Try this:

<table>
    <ng-container *ngFor="let row of rows">
    <tr>
      <th>Head 1</th>
      <th>Head 2</th>
    </tr>
    <tr>
      <td>{{row.data1}}</td>
      <td>{{row.data2}}</td>
    </tr>
    </ng-container>
  </table>
justcode
  • 1,562
  • 3
  • 14
  • 25