I'm submitting a ... (check one with "x")
[x] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, post on Stackoverflow or Gitter
Current behavior
when columnMode is set to flex, resizing the columns will not resize the rows columns
Expected behavior
rows should also resize to the header column width
Reproduction of the problem
can reproduce on the demo site:
http://swimlane.github.io/ngx-datatable/#flex
What is the motivation / use case for changing the behavior?
Please tell us about your environment:
windows 10
Table version: 0.8.x
10.0.5
Angular version: 2.0.x
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 ]
Chrome (60.0.3112.90),
Firefox (54.0.1),
Edge,
IE 11
but more likely all of them
I have faced the same problem, there are a lot of issues allredy opened about this bug, #681 for instance. When 'resize' event is fired column width in flex mode recalculate pro rata with flexGrow values but exactly the same as initially. Resized column and its flexGrow is taking into account when the table width destributed to columns what leads to the permanently the same columns widht.
Simle workaround here is inject ngx-datatable to parent component via @ViewChild for example, and set columnMode 'force' manually in AfterViewInit hook. As result columns will behave as in 'force' mode, but only for resizing.
I just noticed this. I think the flex column distribution alog is kinda buggy. I'm wondering how many ppl actually use it, might be worth removing.
Thanks for your job, cool table. Of course, I can鈥檛 speak for all the community, but for me it's really important to define column width in some relative units. And for initial column rendering and column toggling flex mode works perfect, while there are some bugs with column toggling in force mode. IMHO flex mode is OK, except resizing, when flex recalculation not expected, and column should behave like in force mode.
@mishkolesnikov thanks for the workaround, helped a lot with further mocking up.
I've found that force mode takes care of almost all my needs when the parent is set to a percentage. of course when the screen gets small on a big table, the column names and cell text get overflowed.
feel free to close this if #681 is relevant enough for this issue.
@mishkolesnikov thank you so much for the workaround!
Here's actual code how to do it:
import { DatatableComponent, ColumnMode } from '@swimlane/ngx-datatable';
...
@ViewChild(DatatableComponent) ngxDatatable: DatatableComponent;
ngAfterViewInit() {
this.ngxDatatable.columnMode = ColumnMode.force;
}
@mishkolesnikov Thanks for the workaround, worked like a charm for me too. Any real progress on this issue?
@amcdnl don't remove it, it's very useful
it is useful! Thanks a lot. I still had some problems when wanting to switch between different views on mobile view and web-view when f.e. using chrome mobile emulator. Thats why I had to switch between flex-mode and force-mode afterwards. To accomplish that, I had to switch to flex-mode whenever a window:resize event is being caught, and throw another event myself with a debounceTime to be able to apply the force-mode afterwards. (Maybe someone else has the same problem)
@lukasT Could you please show how you implemented it? I need that same behavior within my Datatable
@HackPoint this is what I've being working with (Not very beautiful but does the job)
@HostListener('window:resize')
resize($event) {
setTimeout(() => {
this.table.columnMode = ColumnMode.flex;
});
this.resizeEvent.next($event);
}
// extra event to be able to apply debounceTime in order to execute specific actions like setting
// the columnMode AFTER the actual resize happened.
resizeEvent: Subject<MouseEvent> = new Subject<MouseEvent>();
ngAfterViewInit() {
this.resizeEvent.debounceTime(this.refreshForceColumnModeDelay).subscribe(() => {
this.onResize();
});
}
onResize() - method is checking whats the current ColumnMode of the wrapped table and does the switch to force if not yet set.
@lukasT Thank you very much
@lukasT tell me please did you handled some server virtual scrolling with this grid?
@HackPoint what is server virtual scrolling? :D
My workaround (hack) for this was to use ColumnMode.force and change the utils/math.ts:forceFillColumnWidths() function. It now resizes the columns proportionally to what the original size was for each column:
@@ -116,12 +116,17 @@ export function forceFillColumnWidths(
do {
additionWidthPerColumn = remainingWidth / columnsToResize.length;
exceedsWindow = contentWidth >= expectedWidth;
+ const totalWidth = columnsToResize.reduce((total, col) => total + col.width, 0);
for (const column of columnsToResize) {
if (exceedsWindow && allowBleed) {
column.width = column.$$oldWidth || column.width || defaultColWidth;
} else {
- const newSize = (column.width || defaultColWidth) + additionWidthPerColumn;
+ // const newSize = (column.width || defaultColWidth) + additionWidthPerColumn;
+ // Distribute the remaining width proportionally to each column based on its initial width
+ const oldSize = column.width || defaultColWidth;
+ const additionalWidthForCol = Math.ceil(oldSize / totalWidth * remainingWidth);
+ const newSize = oldSize + additionalWidthForCol;
if (column.minWidth && newSize < column.minWidth) {
column.width = column.minWidth;
So, that's an option if you feel like branching the repository.
Other solution:
@ViewChild('table') set datatable(table:DatatableComponent) {
table.columnMode=ColumnMode.force;
}
or
@Directive({
selector: '[ngxColumnMode]'
})
export class ColumnMode implements AfterViewInit {
constructor(@Host() private datatable: DatatableComponent) {
this.datatable.columnMode = ColumnMode.flex;
}
ngAfterViewInit(): void {
this.datatable.columnMode = ColumnMode.force;
}
}
Most helpful comment
@mishkolesnikov thank you so much for the workaround!
Here's actual code how to do it: