ngx-datatable
ngx-datatable copied to clipboard
Datatable width resize problem. datatable-scroller and datatable-header-inner does not resize after initial load
I'm submitting a ... (check one with "x")
[x] bug report => search github for a similar issue or PR before submitting
Current behavior datatable-scroller and datatable-header-inner(also it's children) doesn't resize on width after datatable inital load
Expected behavior They should resize... https://cl.ly/1U090c3Q0X2S
Reproduction of the problem You can represent the problem anywhere.
What is the motivation / use case for changing the behavior? This is a bug.
Please tell us about your environment: macOS Sierra, Chrome Version 60.0.3112.101
-
Table version: 9.3.0, 10.0.5
-
Angular version: 4.3.3
-
Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
-
Language: [all | TypeScript X.X | ES6/7 | ES5]
I have also encountered this. Some things I've tried is to trigger recalculate table but that does not fix the problem.
Same here. After ngShow/ngIf the table didn't recalculate columns width until viewport resize event is manually triggered.
The ngx-datatable also doesn't recalculate height in the same situation, if data updates while the table is not visible it decides each virtual page can only contain a single row. You get a messed up view until the table is resized through e.g. a browser window resize.
Here's a hack I implemented in the component containing the datatable:
this.cd.markForCheck();
setTimeout(() => {
document.body.style.width = window.innerWidth - 1 + 'px';
this.table.recalculate();
this.table['cd'].markForCheck();
document.body.style.width = 'auto';
}, 0);
The hack in my previous comment isn't actually reliable. The only way to fix this problem is to revert to v10.5.0. Please fix this.
@webmatrixxxl Hi i have simple solution for this. You just need to trigger window resize event.
window.dispatchEvent(new Event('resize'));
@webmatrixxxl I tried that once and it worked, but the last time I tried, didn’t work.
Here i found a hack for "datatable-scroller" resize issue...
Ngx-Datatable version which i am using right now
"@swimlane/ngx-datatable": "11.1.7",
setTimeout(() => {
$('#mainNgxTable .datatable-scroll').width('100%');
}, (500));
#mainNgxTable id of ngx-datatable,
<ngx-datatable id="mainNgxTable" ... >
it is best if you call this init data/rows for ngx-datatable
I am doing in Angualr 2
this.dataService
.getData()
.subscribe(
data => {
this.rows = data.rows; // init or loading data, came in response of restApi call
setTimeout(() => {
$('#mainNgxTable .datatable-scroll').width('100%');
}, (500));
},
error => {
//handle error
}
);
Well
It seems that the scroller width is calculated in the body.component.ts file
@Input() set columns(val: any[]) {
this._columns = val;
const colsByPin = columnsByPin(val);
this.columnGroupWidths = columnGroupWidths(colsByPin, val);
}
Now this.columnGroupWidths dictates the width of the scroller and this is sadly not recalculated on ngxDatatable.recalculate(); function.
What I did is every time I want to recalculate I firstly reset the columns pointer in the datatable and then recalculate. Seemed to fix the issue for me!
component.ts
class X {
@ViewChild(DatatableComponent) ngxDatatable: DatatableComponent;
recalculate() {
this.columns = [...this.columns]; //This is input into <ngx-datatable>
this.ngxDatatable.recalculate(); //ngx-datatable reference
}
...
}
component.html
<ngx-datatable
[columns]="columns"
[rows]="rows">
</ngx-datatable>
columnGroupWidths
can you show us how you did that?, did you create a recalculate function ?
I used the recalculate function on DatatableComponent
@ViewChild(DatatableComponent) datatable: DatatableComponent;
Adding a simple css rule for .datatable-scroll
display: inherit !important;
works for me
I had similar problem with the table width not changing properly after mobile device screen rotations. @karljv solution works for me. I also use a rotation change host listener to trigger the recalculation:
@HostListener('window:orientationchange', ['$event']) onOrientationChange(event) { ... }
I have tried all possible approaches and end up disabling scrolling and implementing paging ... it worked for me Ex: //scrollX: "99.95%", //scrollY: 300, paging: true,
Is this still an open issue for everyone? I am running into a similar issue with the latest release and was wondering what the recommended workaround is or if anyone has a fork that fixes up the issue. (cc @marjan-georgiev in case there is a fix already in place from another issue)
This is not a solution that I would like, but to temporarily fix it, what I do is the following:
component.html
<mat-tab-group (selectedIndexChange)="isAnimationDone= false" (animationDone)="isAnimationDone= true;">
<mat-tab>
<ngx-datatable class="material" [rows]="licenses" *ngIf="isAnimationDone">
...
...
...
</ngx-datatable>
</mat-tab>
</mat-tab-group>
component.ts
isAnimationDone: boolean = true;
@HostListener('window:resize', ['$event'])
onResize(event){
this.isAnimationDone=false;
setTimeout(() =>this.isAnimationDone=true, 1000);
}
@ViewChild("table") table: DatatableComponent;
@HostListener('window:resize', ['$event']) onResize(event) { this.table.recalculate(); this.table.recalculateColumns(); }
This works for me.
@webmatrixxxl Hi i have simple solution for this. You just need to trigger window resize event.
window.dispatchEvent(new Event('resize'));
ngAfterViewChecked():void{ window.dispatchEvent(new Event('resize')); }
it works!
Here's a hack I implemented in the component containing the datatable:
this.cd.markForCheck(); setTimeout(() => { document.body.style.width = window.innerWidth - 1 + 'px'; this.table.recalculate(); this.table['cd'].markForCheck(); document.body.style.width = 'auto'; }, 0);
The problem with this approach is that if you have a filtering table, i.e. a search functionality on the table, the search feature breaks.
These classes worked for me without adding any hooks or resize method.
.datatable-header-inner{ width: 100% !important; }
.datatable-scroll{ display: inherit !important; }
.datatable-row-center{ width: 100% !important; }
.datatable-body-row{ width: 100% !important; }
@webmatrixxxl Hi i have simple solution for this. You just need to trigger window resize event.
window.dispatchEvent(new Event('resize'));
This worked for me
@webmatrixxxl Hi i have simple solution for this. You just need to trigger window resize event.
window.dispatchEvent(new Event('resize'));
I have made so many try but this things works for me. Thank you.
window.dispatchEvent(new Event('resize'));
this one work with me many thanks
I had a similar problem and it was resolved thanks to everyone.
Create a directive
that detects width differences and raises a resize event
import { Directive, AfterContentChecked } from '@angular/core';
import { DatatableComponent } from '@swimlane/ngx-datatable';
@Directive({ selector: '[appNgxTableResizer]' })
export class NgxTableResizerDirective implements AfterContentChecked {
constructor(private table: DatatableComponent) {}
ngAfterContentChecked(): void {
const timerId = setInterval(() => {
if (this.table && this.table.element.clientWidth !== this.table._innerWidth) {
window.dispatchEvent(new Event('resize'));
} else {
clearInterval(timerId);
}
}, 100);
}
}
set directive
<ngx-datatable
appNgxTableResizer
...>
</ngx-datatable>
load module
@NgModule({
declarations: [XXXComponent, NgxTableResizerDirective],
exports: [XXXComponent, NgxTableResizerDirective],
})
export class xxx {}
Adding a simple css rule for
.datatable-scroll
display: inherit !important;
works for me
I used this way to avoid !important
and also scope it to just the table(s) I needed to fix with .my-class
.
.my-class .ngx-datatable .datatable-body .datatable-scroll {
display: inherit;
}
That's worked for me.. my package version: @swimlane/[email protected] As @manjeetyadv mention above I add css from this https://github.com/swimlane/ngx-datatable/issues/923#issuecomment-678753412
And also add this code:
@ViewChild('tableWrapper') tableWrapper;
@ViewChild('dataListTable') dataListTable: DatatableComponent;
private currentComponentWidth;
ngAfterViewChecked(): void {
if (this.dataListTable && this.dataListTable.recalculate && (this.tableWrapper.nativeElement.clientWidth !== this.currentComponentWidth)) {
this.currentComponentWidth = this.tableWrapper.nativeElement.clientWidth;
this.dataListTable.recalculate();
this._changeDetectorRef.detectChanges();
}
}
in html:
<div #tableWrapper>
<!-- Table -->
<ngx-datatable #dataListTable...