3

I am using ngx-datatable to render data table with grouping of rows.

Here is the HTML code

<ngx-datatable [rows]="data" [loadingIndicator]="loadingIndicator" [groupExpansionDefault]="false"
    [groupRowsBy]="'Name'">
    <!-- Header Template -->
    <ngx-datatable-group-header [rowHeight]="60">
        <ng-template let-group="group" let-expanded="expanded" ngx-datatable-group-header-template>
            <div class="table-group-header group-header">
                <span style="cursor: pointer" [class.datatable-icon-right]="!expanded"
                    [class.datatable-icon-down]="expanded" (click)="expandGroup(group)">
                    {{group.key}}
                </span>
            </div>
        </ng-template>
    </ngx-datatable-group-header>

    <ngx-datatable-column name="Name" [width]="200">
        <ng-template let-row="row" ngx-datatable-cell-template>
            {{row.name}}
        </ng-template>
    </ngx-datatable-column>
    <ngx-datatable-column name="Cost" [width]="100">
        <ng-template let-row="row" ngx-datatable-cell-template>
            {{row.cost}}
        </ng-template>
    </ngx-datatable-column>
    <ngx-datatable-column name="Number" [width]="50">
        <ng-template let-row="row" ngx-datatable-cell-template>
            {{row.number}}
        </ng-template>
    </ngx-datatable-column>
</ngx-datatable>

Here is how it looks

enter image description here

The examples I have seen provide one template that will be rendered in header row. What I want is total of each column in the header row (marked red boxes in image). How can I provide multiple columns in group header row as well ?

I tried providing all the values under same single template with proper width, but the problem is that width is fixed for div in the template and as columns size can be changed in ngx-datatable so header row template layout will not fit (as I provided fixed width).

Here is how I have done this

<ngx-datatable-group-header [rowHeight]="60">
    <ng-template let-group="group" let-expanded="expanded" ngx-datatable-group-header-template>
        <div class="table-group-header group-header">
            <span style="cursor: pointer" [class.datatable-icon-right]="!expanded"
                [class.datatable-icon-down]="expanded" (click)="expandGroup(group)">
                <span style="width: 300px;">
                    {{group.key}}
                </span>
                <span style="width: 100px;">
                    {{sumProperty(group.value, 'cost') | number: 0}}
                </span>
                <span style="width: 50px;">
                    {{sumProperty(group.value, 'number')}}
                </span>
            </span>
        </div>
    </ng-template>
</ngx-datatable-group-header>
4
  • 2
    Ever found a way? I'm having the exact same issue... Commented Jun 28, 2019 at 13:42
  • not yet, but will share the answer if got an answer !! Commented Jun 29, 2019 at 6:17
  • there are any solution for this issue??? Commented Nov 6, 2019 at 13:45
  • @VictorOrletchi at least a partial one... Commented Jan 3, 2020 at 23:31

1 Answer 1

1

After hours of crying I have found a partial solution for this. It's not without compromises, but for me it works good enough.

First of all, set an initial width for your columns. You have already done that by using [width]. However, I would recommend using binding a columns object as model to your datatable:

Then, register a [resize] callback on your ngx-datatable:

<ngx-datatable
        #loadTable
        class="material"
        [rows]="loadData$ | async"
        .....
        [columns]="columns"
        ...
        ...
        (resize)="onResize($event)"
      >

corresponding .ts file's constructor:

this.columns = [
    { 
      name : 'Name', 
      prop : 'name',
      width : 200
    }, 
    ....
 ]

Then, in your callback:

onResize(event){
    this.columns.find(col => col.name == event.column.name).width = event.newValue
  }

So far so good. We have managed to keep track of resize events regarding our columns. If you want to keep using your html column definitions you will have to define an array of mappings for [colName, newSize] in your component and store the changed sizes there.

Now for the hacky part.... Instead of applying fixed widths to your spans styling, use [ngStyle] and bind to a callback:

<span [ngStyle]="getWidth('Name')">
  <b>Test</b>
</span>

And then, in your component:

getWidth(rowName){
let val = this.columns.find(col => col.name == rowName).width + "px"
    return {"width" : val}
}

Note, this will set the width of the span to the exact beginning of the next column. This is, however, not the beginning of the text in the column as there is a padding applied. In my case, this padding is 19.2px. In case you want to compensate for this, simply add the padding to the newly applied width.

I am myself quite new to angular and typescript in general, so sorry if anyone feels dirty after reading this.

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.