Reputation: 15598
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
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>
Upvotes: 3
Views: 6044
Reputation: 2847
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.
Upvotes: 1