Open sapabg opened 4 years ago
Same issue here after upgrading to v18.0.0 from 15.0.2. Removing [scrollbarV]="true"
allows rows to show but can't seem to get both working with vertical scroll
To anyone who run into this or similar problems:
ngx-datatable calculates how many rows to show based on available space, height of items, header and footer ext. This calculation is performed once when input changes.
If ngx-datatable somehow is coerced into making this calculation at a bad time (no data, control not visible ect.) then it seems to fallback to 1 row.
We have ngx-datatable inside a tab with data being reloaded periodically. If ngx-datatable were hidden when background fetch occurred, then we would get 1 row visible. We fixed this by detecting when tab becomes visible (IntersectionObserver), and changing one of the ngx-datatable parameters to trigger a recalculation,
I tried to refresh the table and even called the recalculate() function, but in Firefox, and only in Firefox, it still shows everything in one row. It happens only with [scrollbarV]="true" setup
This issue has been affecting us here too since the last 2 days. Only seems to be present for the latest version of firefox.
Here's a stackblitz: https://stackblitz.com/edit/angular-nhma2y?file=src%2Fmain.ts
This issue has been affecting us here too since the last 2 days. Only seems to be present for the latest version of firefox.
Here's a stackblitz: https://stackblitz.com/edit/angular-nhma2y?file=src%2Fmain.ts
Same issue for me, was working in Firefox 124.0.1 and since 126.0 it breaked, changed nothing in my code. Chromium browsers work fine
NOTE: I am not positive if this is related to the original reported problem, since my problem and the last commenters problem seems to be from a recent Firefox change. The original post doesn't specify their browser, so it is hard to say if they were maybe using an old or non-typical browser that had an issue with the transform
or translate3d
features.
I think they were referring to a problem with how they were using ngx-datatable
and not necessarily a bug with ngx-datatable
, but it isn't clear. So, I may open another issue for this Firefox problem.
I took a look at this and I didn't get all the way into what exactly was changed in Firefox, but I found enough to hopefully fix our applications, at least.
Here is what I found:
In ngx-datatable
, the rows are positioned using transform: translate3d(${x}px, ${y}px, 0px)
. The transform is being set on an object that will be applied to the element's style
property. That object is build with the following translateXY()
function:
https://github.com/swimlane/ngx-datatable/blob/5eed8493fa016bcbf49f7fe7d9bc39e41916a4e7/projects/swimlane/ngx-datatable/src/lib/utils/translate.ts#L12-L24
Since ngx-datatable
is using vendor prefixes, the resulting object will be { '-moz-transform': `translate3d(${x}px, ${y}px), 0px)`, 'backface-visibility': 'hidden' }
in Firefox.
If ngx-datatable
was setting those properties directly on the element's styles object then there would not be any problem, but that task is handed off to Angular's ngStyle
directive. https://github.com/swimlane/ngx-datatable/blob/5eed8493fa016bcbf49f7fe7d9bc39e41916a4e7/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts#L55
Angular's ngStyle
directive iterates the object's properties and applies them to the element's style object, which is correct and what we want it to do. The problem is how it does that, which should not be a problem, but Firefox apparently made a change that causes Angular's way to be a problem. They use Renderer2
to set the properties, using the setProperty
method. So, the ngStyle
directive will end up setting the properties, from the object I mentioned above, the following way:
element.style.setProperty('-moz-transform', `translate3d(${x}px, ${y}px, 0px)`, '')
element.style.setProperty('backface-visibility', 'hidden')
Firefox has an open issue, https://bugzilla.mozilla.org/show_bug.cgi?id=1886134, which is the source of the problem, I think. This is mainly a guess, since I didn't dig into Firefox's code, but I assume the vendor prefix was removed from the core and still exists in the CSS engine. So, I assume setProperty
gets handled by the core that no longer recognizes the property and just ignores it without saying anything, for some reason. If you set the property on the element's style
property directly then I assume that is passed on to the CSS engine and it still recognizes the property.
If you want to test fixes, without reverting to an older version of Firefox, you can toggle the feature back to how it used to be by going to about:config
and setting layout.css.prefixes.transforms
to true
.
Possible fix:
I haven't done thorough testing to confirm, but is there a reason to still bother with vendor prefixes? At this point, shouldn't all the browsers that Angular supports, also support transform
without the need for a vendor prefix? If so, the problem should be fixable by dropping that functionality from ngx-datatable
and just using the unprefixed transform
property/rule.
If, the prefix is still potentially needed, would it be fine to just set both the prefixed and non-prefixed? So, the return from translateXY()
on Firefox would be { '-moz-transform': `translate3d(${x}px, ${y}px), 0px)`, 'transform': `translate3d(${x}px, ${y}px), 0px)`, 'backface-visibility': 'hidden' }
Workarounds:
I didn't find a workaround that I really like, but these may work until ngx-datatable
or Firefox is updated.
Option 1:
Since, Angular uses Renderer2
, you may be able to provide a different Renderer2
that modifies the setProperty
method to replace the prefix or not use CSSStyleDeclaration.setProperty
. I haven't looked into doing this, yet. It may be simple, but I wasn't sure if there was a safe generic way to do this, since that provider seems to be initialized by a factory and injects providers that don't seem to have exports that were simple to find.
Option 2: I do not like to use a monkey-patch, but it is small and should be fine. I would not want to rely on it as a permanent fix, though.
(() => {
const original = CSSStyleDeclaration.prototype.setProperty;
CSSStyleDeclaration.prototype.setProperty = function () {
const args = [...arguments];
if (args[0] === '-moz-transform') {
args[0] = 'transform';
}
return original.apply(this, args);
};
})();
Option 3:
You could patch the translateXY
function in your node_modules/@swimlane/ngx-datatable
, but I don't like to touch dependency files. If you are already using a modified build config then maybe you could just transform it there, but I don't have a lot of experience doing that.
I have tried with Option 1
from @Marklb comment above and it worked for me. I've created a service which implements Renderer2 and then it overrides the setStyle
method. Below are the steps:
First you need a class which implements RendererFactory2
:
import { ɵDomRendererFactory2 as DomRendererFactory2 } from '@angular/platform-browser';
@Injectable()
export class YourRendererFactory implements RendererFactory2 {
readonly factory = inject(DomRendererFactory2);
createRenderer(hostElement: any, type: RendererType2): Renderer2 {
return new YourRendererService(this.factory.createRenderer(hostElement, type));
}
}
Then I created the YourRendererService
class:
export class YourRendererService implements Renderer2 {
constructor(readonly delegate: Renderer2) {}
get data(): {[key: string]: any} {
return this.delegate.data;
}
createElement(name: string, namespace?: string) {
return this.delegate.createElement(name, namespace);
}
// ...
// ...
// ...
// Modified name prop FF issue
setStyle(el: any, style: string, value: any, flags?: RendererStyleFlags2): void {
const styleWithoutFFPrefix = style.replace(/^(-moz-)/, '');
return this.delegate.setStyle(el, styleWithoutFFPrefix, value, flags);
}
}
Last step is to provide it in your module like:
{ provide: RendererFactory2, useClass: YourRendererFactory }
I'm submitting a
Current behavior
<ngx-datatable *ngIf="(firm$ | async) && (contragents$ | async)"
table
This code produces a table that is scrollable but there is only one visible row - basically one row per page.
Expected behavior
It is suppose to show 10 rows per page or at least allow me to set how high or how many elements should the virtual scroll show.
Reproduction of the problem tried to create a plunker but I can't make it work at all.
Please tell us about your environment:
"@swimlane/ngx-datatable": "^17.1.0",
I copied the code from the demo and the result is the same - only one row but the table is scrollable.