0

I'm trying to make a table with sub-columns from an array of column object that can itself contain sub-columns.

The header object :

export class ListHeader {
    id: string;
    label: string;
    type: int;
    subColumns?: ListHeader[];
}

Table component partial code

columns: ListHeader[];
columnsWithSubColumns: ListHeader[];

constructor(){
   this.columns = [{
        id: "AC1",
        label: "AC1",
        type: 1
      },
      {
        id: "AC3",
        label: "AC3",
        type: 1
      },
      {
        id: "AC2",
        label: "AC2",
        type: 1,
        subColumns: [
          {
            id: "ColB",
            label: "ColB",
            type: 1
          },
          {
            id: "ColA",
            label: "ColA",
            type: 1
          },
          {
            id: "ColC",
            label: "ColC",
            type: 1
          }
        ]
      }
   ];
   this.columnsWithSubColumns = this.columns
            .filter(c => typeof c.subColumns !== 'undefined' && c.subColumns !== null && c.subColumns.length > 1);
}

The HTML :

<table>
    <thead>
        <tr>
            <th *ngFor='let key of columns' [id]='key.id'>
                {{ key.label }}
            </th>
        </tr>
        <tr>
            <th *ngFor='let key of columnsWithSubColumns '>
                <--! Can't figure how to do from there -->
            </th>
        </tr>
    </thead>
  <--! tbody, etc... -->
</table>

I tied multiple solution, by modifying the HTML and/or the underlying Typescript, but I'm unable to find a way to show correctly the sub-columns. Either they shows under the wrong column, or don't shows at all.

I've found a working static table that does wore or less what I want (http://jsfiddle.net/8qycxkv9/), but I'm looking to make it dynamics.

As such, I'm trying to create a second array of ListHeader, from all subHeaders arrays in the columns Array. I managed to filter out the columns without subcolumns, but can't find a way to go further.

I'm open to any implementation, the only constrain is keeping as it the ListHeader object.

2
  • Please specify the problem that you are experiencing. Commented Oct 21, 2019 at 11:49
  • I added more detail, please ask if you need more. Commented Oct 21, 2019 at 12:03

2 Answers 2

2

You need to use attribute "colspan" in first array, which mean how many subheaders will be under this header.

You get something like this:

<table>
    <thead>
        <tr>
            <th *ngFor='let key of columns' [id]='key.id' colspan=key.subColumns.length>
                {{ key.label }}
            </th>
        </tr>
        <tr>
            <ng-container *ngFor='let key of columns'>
                <th *ngFor='let subheader of key.subColumns'>
                    {{subheader.label}}
                </th>
            </ng-container>
        </tr>
    </thead>
  <--! tbody, etc... -->
</table>

If some of your columns don't have subtitles you can do something like this:

<table>
    <thead>
        <tr>
            <ng-container *ngFor='let key of columns'>
                <th *ngIf='key.subColumns' [id]='key.id' [attr.colspan]=key.subColumns.length>
                    {{ key.label }}
                </th>
                <th *ngIf='!key.subColumns' [id]='key.id' [attr.rowspan]=2>
                    {{ key.label }}
                </th>
            </ng-container>
        </tr>
        <tr>
            <ng-container *ngFor='let key of columns'>
                <th *ngFor='let subheader of key.subColumns'>
                    {{subheader.label}}
                </th>
            </ng-container>
        </tr>
    </thead>
  <--! tbody, etc... -->
</table>

Then columns with subtitles would be wide, and columns without it would be tall.

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

1 Comment

Angular cannot access 'collspan' directly, you have to use 'attr.colspan'. "[attr.rowspan]='key.subColumns.length' " won't work is the is a column with no subcolumn. But I like the idea of the ng-container.
1

try this it is working as you intended.

<table>
  <thead>
      <tr>
          <ng-container *ngFor='let key of columns'>
              <th *ngIf='key.subColumns' [id]='key.id' [attr.colspan]=key.subColumns.length>
                  {{ key.label }}
              </th>
              <th *ngIf='!key.subColumns' [id]='key.id' [attr.rowspan]=2>
                  {{ key.label }}
              </th>
          </ng-container>
      </tr>
      <tr>
          <ng-container *ngFor='let key of columnsWithSubColumns'>
          <th *ngFor="let sub of key.subColumns">
            {{sub.label}}
          </th>
          </ng-container>
      </tr>
  </thead>
</table>

6 Comments

Looks like it works with only one column with sub-column. Is there a way to make it work with more sub-columns ?
I have tested it with more than one sub-column and it is working fine. can you tell your scenario?
I have two column, each having 3 sub-column. It gives me something like this : jsfiddle.net/6czb0s7o
Do you want those sub-columns to be inside 1 tr tag then? can you show your intended solution design?
Yes, I intend to get the following result : jsfiddle.net/w5d4s6y8
|

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.