Open NadeemShakya opened 3 years ago
Confirmed, can be reproduced using the demo. https://cdn.vaadin.com/vaadin-grid/5.6.10/demo/#grid-columns-demos
Workaround:
grid.$.table.addEventListener('scroll', () => {
const scrollLeft = grid.$.table.scrollLeft;
grid.recalculateColumnWidths()
grid.$.table.scrollLeft = scrollLeft;
});
I recommend using some kind of throttling for this however, as running recalculateColumnWidths
on every single scroll event would negatively affect scrolling performance.
Workaround:
grid.$.table.addEventListener('scroll', () => { const scrollLeft = grid.$.table.scrollLeft; grid.recalculateColumnWidths() grid.$.table.scrollLeft = scrollLeft; });
I recommend using some kind of throttling for this however, as running
recalculateColumnWidths
on every single scroll event would negatively affect scrolling performance.
@tomivirkki I'm afraid it won't work. Because what happens is:
scrollLeft = 480
grid.recalculateColumnWidths()
will work as intended and will scroll back the grid to its horizontal starting point i.e. 0grid.$.table.scrollLeft = 480
Now, this is where the problem begins:
grid.recalculateColumnWidths()
is buggy, when it gets executed, it scrolls the grid from 480 to 0 itself, what this does is, triggers the scroll event again. Now,
scrollLeft = 0
grid.recalculateColumnWidths()
will work as intended and will scroll back the grid to its horizontal starting point i.e. 0grid.$.table.scrollLeft = 0
This way, the problem still remains.
Maybe you can set a flag to disable the listener logic while recalculate is being run:
myFlag = true
;myFlag = false
;@tomivirkki :stop_sign: Ooooops! It didn't work! :cry:
Because, I'm using LitElement and as far as I understand, LitElement performs batch rendering to the updated props. So, in that case,
myFlag = true
;myFlag = false
;myFlag = false
, so our flag logic here won't work as the subsequent chunk of code fires again.Ah, I think what's going on. We're probably using different grid versions. With the newest version, the original workaround works just fine. See it running live at https://productive-neat-manuscript.glitch.me/ (source: https://glitch.com/edit/#!/productive-neat-manuscript)
We have the same issue when using column width recalculation on a column sort. The snippet from Tomi helped to solve the issue in that case.
Update on this issue. Using recalculateCW with auto width columns can lead to mispositioned headers:
Not sure, if this is part of this issue or something different, but it relates at least to the given workaround
To fix that, another scroll left helps:
let left = this.$.table.scrollLeft;
let top = this.$.table.scrollTop;
this.recalculateColumnWidths();
this.$.table.scrollLeft = left;
this.$.table.scrollTop = top;
this.$.table.scrollLeft = this.$.table.scrollLeft - 1;
Some sample code to reproduce the issue with the left scroll. It also contains the basic workaround, that will keep the scroll position. This one will lead to misaligned headers. It also contains the additional workaround to realign the headers correctly (both commented out)
var grid = new Grid<Integer>();
grid.addThemeVariants(GridVariant.LUMO_COLUMN_BORDERS);
grid.setItems(IntStream.range(0, 500).boxed().collect(Collectors.toList()));
grid.setColumnRendering(ColumnRendering.LAZY);
DataProvider<Integer, ?> dataProvider = grid.getDataProvider();
dataProvider.addDataProviderListener(event -> {
// using this instead of the normal recalc fixes the left jump
// grid.getElement().executeJs("""
// if(this && this.recalculateColumnWidths) {
// let left = this.$.table.scrollLeft;
// let top = this.$.table.scrollTop;
// this.recalculateColumnWidths();
// this.$.table.scrollLeft = left;
// this.$.table.scrollTop = top;
//
// // this fixes the problem with the misaligned headers
// left = this.$.table.scrollLeft;
// this.$.table.scrollLeft = this.$.table.scrollLeft - 0.1;
// setTimeout(() => {
// this.$.table.scrollLeft = left;
// }, 300);
// }""");
grid.recalculateColumnWidths();
});
for (int i = 0; i < 50; i++) {
grid.addColumn(item -> "very very very very very very very very very very very very very very very long string value").setHeader("HELLO WORLD").setAutoWidth(true);
}
add(new Button("Refresh", e -> grid.getDataProvider().refreshAll()), grid);
grid.setSizeFull();
setSizeFull();
Description
I've listened to scroll events and added my own logic with something like
grid.$.table.addEventListener('scroll', grid.recalculateColumnWidths()).
This causes the grid columns with
auto-width
to update.Now, when I scroll the grid vertically, the code works as expected without any issues.
While scrolling the grid horizontally (I have a large table so have a horizontal scrollbar on the grid), the following happens:
Expected outcome
I wish the grid to scroll horizontally to my desired location and stay fixed.
Actual outcome
The grid scrolls back to the starting position and doesn't stick to the location where I scrolled the grid.
In the above image, the grid has scrolled automatically to this starting position from my desired location.
Browsers Affected
@tomivirkki @web-padawan