Reputation: 1227
Do you have any ideas how can I translate "Items per page" in Angular's mat-paginator
tag? The mat-paginator
is an element from Material Design.
Upvotes: 79
Views: 77783
Reputation: 392
I like this solution the best: https://stackoverflow.com/a/72859986/18865220 by Alejandro Araujo .
I'd also add that you can translate using Angular's internationalization by adding 'localize' to the strings:
constructor(private paginatorIntl: MatPaginatorIntl) {
paginatorIntl.nextPageLabel = $localize`Next page`;
paginatorIntl.previousPageLabel = $localize`Previous page`;
paginatorIntl.lastPageLabel = $localize`Last page`;
paginatorIntl.firstPageLabel = $localize`First page`;
paginatorIntl.itemsPerPageLabel = $localize`Items per page:`;
}
You can then generate xlf files (providing you've added Angular's built in internationalization to your project) by running "ng extract-i18n --output-path src/locale". This will generate an xlf file that you can copy and add your target translation text below the source text. This means you don't have to add a text for each target language in your constructor. As mentioned, in order for this to work, you'll to add Angular's i18n to your project. The Angular docs have a good video with step by step instructions on how to do that: Angular docs
Upvotes: 0
Reputation: 8069
You can use the MatPaginatorIntl
for this. Will Howell made an example that no longer works, so here is an updated version (with Dutch) and step-by-step guidance.
MatPaginatorIntl
from @angular/material
into your application.import { getDutchPaginatorIntl } from './app/dutch-paginator-intl';
in main.ts
fileprovider
for the Paginator inside of the main.ts
file, so it takes the translations of your local file (instead of English as default language):providers: [
{ provide: MatPaginatorIntl, useValue: getDutchPaginatorIntl() }
]
paginatorIntl.itemsPerPageLabel = 'Items per pagina:';
paginatorIntl.firstPageLabel = 'Eerste pagina';
paginatorIntl.previousPageLabel = 'Vorige pagina';
paginatorIntl.nextPageLabel = 'Volgende pagina';
paginatorIntl.lastPageLabel = 'Laatste pagina';
paginatorIntl.getRangeLabel = dutchRangeLabel;
Example on StackBlitz with the paginator translations file as starting point.
June 2018 - Update to Angular 6.x
This updated Example on StackBlitz is upgraded to Angular 6.x to accommodate the latest version of the framework. Only packages have changed, nothing inside the paginator has changed.
June 2019 - Update to Angular 8.x
This updated Example on StackBlitz is upgraded to Angular 8.x to accommodate the latest version of the framework. Only packages have changed, nothing inside the paginator has changed.
February 2020 - Update to Angular 9.x
This updated Example on StackBlitz is upgraded to Angular 9.x to accommodate the latest version of the framework. Package versions have changed. Major change is the way to import from Angular Material. You cannot import from Material root anymore. You need to specify the import from the module (material/paginator
) itself:
import { MatPaginatorModule, MatPaginatorIntl } from '@angular/material/paginator';
June 2020 - Update to Angular 10.x
This updated Example on StackBlitz is upgraded to Angular 10.x to accommodate the latest version of the framework. Only packages have changed, nothing inside the paginator has changed.
December 2020 - Update to Angular 11.x
This updated Example on StackBlitz is upgraded to Angular 11.x to accommodate the latest version of the framework. Only packages have changed, nothing inside the paginator has changed.
May 2021 - Update to Angular 12.x
This updated Example on StackBlitz is upgraded to Angular 12.x to accommodate the latest version of the framework. Only packages have changed, nothing inside the paginator has changed.
January 2022 - Update to Angular 13.x
This updated Example on StackBlitz is upgraded to Angular 13.x to accommodate the latest version of the framework. Only packages have changed, nothing inside the paginator has changed.
June 2022 - Update to Angular 14.x
This updated Example on StackBlitz is upgraded to Angular 14.x to accommodate the latest version of the framework. Only packages have changed, nothing inside the paginator has changed.
November 2022 - Update to Angular 15.x
This updated Example on StackBlitz is upgraded to Angular 15.x to accommodate the latest version of the framework. Only packages have changed, nothing inside the paginator has changed.
September 2023 - Update to Angular 16.x
This updated Example on StackBlitz is upgraded to Angular 16.x to accommodate the latest version of the framework. Only packages have changed, nothing inside the paginator has changed.
Upvotes: 184
Reputation: 81
After some searchs here is my solutuion , It's a
Daynamique Switcher with ngx-translate and Angular 10.
PaginatorConfig.ts
import { Injectable, OnDestroy } from '@angular/core';
import { MatPaginatorIntl } from '@angular/material/paginator';
import { TranslateService } from '@ngx-translate/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
@Injectable()
export class CustomPaginatorIntl extends MatPaginatorIntl implements OnDestroy {
unsubscribe: Subject<void> = new Subject<void>();
constructor(private translate: TranslateService) {
super();
this.translate.onLangChange
.subscribe(() => {
this.getAndInitTranslations();
});
this.getAndInitTranslations();
}
ngOnDestroy() {
this.unsubscribe.next();
this.unsubscribe.complete();
}
getAndInitTranslations() {
this.translate
.get(['itemsPerPageLabel'])
.subscribe((translation) => {
this.itemsPerPageLabel = translation['itemsPerPageLabel'];
this.changes.next();
});
}
}
app.module.ts
{
provide: MatPaginatorIntl,
useClass: CustomPaginatorIntl,
},
fr.json
{ "itemsPerPageLabel": "Éléments par page "}
en.json
{"itemsPerPageLabel": "Items per page"}
Upvotes: 1
Reputation: 499
Local solution for ES internationalization (just change the values for the labels with the corresponding ones in your language), super direct and without touching the app.moulde:
import { MatPaginatorIntl } from '@angular/material/paginator';
...
constructor(
...
private paginator: MatPaginatorIntl
) {
paginator.nextPageLabel = 'Siguiente';
paginator.previousPageLabel = 'Anterior';
paginator.lastPageLabel = 'Última Página';
paginator.firstPageLabel = 'Primera Página';
paginator.itemsPerPageLabel = 'Registros por Página';
paginator.getRangeLabel = (page: number, pageSize: number, length: number) => {
if (length == 0 || pageSize == 0) { return `0 de ${length}`; }
length = Math.max(length, 0);
const startIndex = page * pageSize;
const endIndex = startIndex < length ? Math.min(startIndex + pageSize, length) : startIndex + pageSize;
return `${startIndex + 1} - ${endIndex} de ${length}`;
};
}
Upvotes: 1
Reputation: 6264
If you use transloco and you need to translate mat-paginator
strings, add this typescript class to your project:
import { Injectable } from '@angular/core';
import { TranslocoService } from '@ngneat/transloco';
import { MatPaginatorIntl } from '@angular/material/paginator';
@Injectable()
export class CustomMatPaginatorIntl extends MatPaginatorIntl {
ofLabel: string = 'of';
constructor(private _translate: TranslocoService) {
super();
this._translate.langChanges$.subscribe((lang) => {
this.getAndInitTranslations();
});
this.getAndInitTranslations();
}
getAndInitTranslations(): void {
this._translate.selectTranslate('paginator.itemsPerPageLabel').subscribe((value) => {
this.itemsPerPageLabel = value;
this.changes.next();
});
this._translate.selectTranslate('paginator.nextPageLabel').subscribe((value) => {
this.nextPageLabel = value;
this.changes.next();
});
this._translate.selectTranslate('paginator.previousPageLabel').subscribe((value) => {
this.previousPageLabel = value;
this.changes.next();
});
this._translate.selectTranslate('paginator.firstPageLabel').subscribe((value) => {
this.firstPageLabel = value;
this.changes.next();
});
this._translate.selectTranslate('paginator.lastPageLabel').subscribe((value) => {
this.lastPageLabel = value;
this.changes.next();
});
this._translate.selectTranslate('paginator.ofLabel').subscribe((value) => {
this.ofLabel = value;
this.changes.next();
});
}
getRangeLabel = (
page: number,
pageSize: number,
length: number,
): string => {
if (length === 0 || pageSize === 0) {
return `0 ${this.ofLabel} ${length}`;
}
length = Math.max(length, 0);
const startIndex = page * pageSize;
const endIndex =
startIndex < length
? Math.min(startIndex + pageSize, length)
: startIndex + pageSize;
return `${startIndex + 1} - ${endIndex} ${
this.ofLabel
} ${length}`;
};
}
Then in your Module
call it like this:
@NgModule({
imports: [
...
TranslocoModule,
],
providers: [
{ provide: MatPaginatorIntl, useClass: CustomMatPaginatorIntl } // >> add this line
]
})
Upvotes: 1
Reputation: 1
If you want to change dynamically the languange, you can enter this code:
this.translate.onLangChange.subscribe(() => {
this.getPaginatorIntl(matPaginatorIntl);
});
private getPaginatorIntl(matPaginatorIntl: MatPaginatorIntl): void {
matPaginatorIntl.itemsPerPageLabel = this.translate.instant('PAGINATOR.ITEM');
matPaginatorIntl.nextPageLabel = this.translate.instant('PAGINATOR.NEXT_PAGE');
matPaginatorIntl.previousPageLabel = this.translate.instant('PAGINATOR.PREVIOUS_PAGE');
matPaginatorIntl.firstPageLabel = this.translate.instant('PAGINATOR.FIRST_PAGE');
matPaginatorIntl.lastPageLabel = this.translate.instant('PAGINATOR.LAST_PAGE');
matPaginatorIntl.getRangeLabel = this.getRangeLabel.bind(this);
matPaginatorIntl.changes.next();
}
private getRangeLabel(page: number, pageSize: number, length: number): string {
if (length === 0 || pageSize === 0) {
return `0 ${this.translate.instant('PAGINATOR.OF')} ${ length }`;
}
length = Math.max(length, 0);
const startIndex = page * pageSize;
// If the start index exceeds the list length, do not try and fix the end index to the end.
const endIndex = startIndex < length ? Math.min(startIndex + pageSize, length) : startIndex + pageSize;
return `${startIndex + 1} - ${endIndex} ${this.translate.instant('PAGINATOR.OF')} ${length}`;
}
It's import insert 'changes.next();' after the edit of the object matPaginatorIntl.
Upvotes: 0
Reputation: 1762
Another version of @Felix's answer, but here you inject your service directly in the function without the need to make or instantiate a class:
In app.module.ts
Add your provider:
providers: [
YourCustomService,
{provide: MatPaginatorIntl, useFactory: getPaginatorI18n, deps: [YourCustomService]}
]
Create a new ts file with your function (Example paginator-i18n.ts
):
import {MatPaginatorIntl} from '@angular/material/paginator';
// This is the word that shows up in the range label
let paginPerRng = '';
const i18nRangeLabel = (page: number, pageSize: number, length: number) => {
if (length == 0 || pageSize == 0) {
return `0 ${paginPerRng} ${length}`;
}
length = Math.max(length, 0);
const startIndex = page * pageSize;
// If the start index exceeds the list length, do not try and fix the end index to the end.
const endIndex = startIndex < length ?
Math.min(startIndex + pageSize, length) :
startIndex + pageSize;
return `${startIndex + 1} - ${endIndex} ${paginPerRng} ${length}`;
};
export function getPaginatorI18n(YourCustomService: customService) {
const paginatorIntl = new MatPaginatorIntl();
// Call the localization methods in your service
paginatorIntl.itemsPerPageLabel = customService.getResource(...);
paginatorIntl.nextPageLabel = customService.getResource(...);
paginatorIntl.previousPageLabel = customService.getResource(...);
paginatorIntl.firstPageLabel = customService.getResource(...);
paginatorIntl.lastPageLabel = customService.getResource(...);
// We localize the word that shows up in the range label before calling the RangeLabel constant
paginPerRng = customService.getResource(...);
paginatorIntl.getRangeLabel = i18nRangeLabel;
return paginatorIntl;
}
Upvotes: 1
Reputation: 309
A simple solution using ngx-translate.
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
constructor(private translate: TranslateService){}
ngOnInit() {
this.translatePaginator();
}
async translatePaginator() {
const label = await this.translate.get('COMMON.ItemsPerPageLabel').toPromise();
this.paginator._intl.itemsPerPageLabel = label;
}
Upvotes: -1
Reputation: 1957
I build on Felix' answers, who builds on Roy's answer.
To account for dynamic language switch, my factory method uses TranslateService
's stream()
method (instead of instance()
) that returns an observable that fires each time language is set. I also call paginator's change.next()
to force redraw.
TranslateService
is able to return a "dictionary" of vocabularies. With the right keys in the JSON file, Object.assign()
can do most of the job.
Finally, I do not re-implement paginator's getRangeLabel()
. Rather I take the old value and replace occurrences of "of" with translated text.
public getPaginatorIntl(): MatPaginatorIntl {
const paginatorIntl = new MatPaginatorIntl();
this.translation.stream('paginator.paginatorIntl').subscribe(dict => {
Object.assign(paginatorIntl, dict);
paginatorIntl.changes.next();
});
const originalGetRangeLabel = paginatorIntl.getRangeLabel;
paginatorIntl.getRangeLabel = (page: number, size: number, len: number) => {
return originalGetRangeLabel(page, size, len)
.replace('of', this.translation.instant('paginator.of'));
};
return paginatorIntl;
}
Here is the fr.json
for example.
{
"paginator": {
"paginatorIntl" : {
"itemsPerPageLabel": "Items par page",
"nextPageLabel": "Page suivante",
"previousPageLabel": "Page précédente",
"firstPageLabel": "Première page",
"lastPageLabel": "Dernière page"
},
"of": "de"
}
}
Upvotes: 3
Reputation: 4595
Modified solution (with Angular 6) based on accepted answer with @ngx-translate:
@NgModule({
imports: [...],
providers: [
{
provide: MatPaginatorIntl, deps: [TranslateService],
useFactory: (translateService: TranslateService) => new PaginatorI18n(translateService).getPaginatorIntl()
}
]
})
export class CoreModule {}
And the PaginatorI18n
:
import { MatPaginatorIntl } from '@angular/material';
import { TranslateService } from '@ngx-translate/core';
export class PaginatorI18n {
constructor(private readonly translate: TranslateService) {}
getPaginatorIntl(): MatPaginatorIntl {
const paginatorIntl = new MatPaginatorIntl();
paginatorIntl.itemsPerPageLabel = this.translate.instant('ITEMS_PER_PAGE_LABEL');
paginatorIntl.nextPageLabel = this.translate.instant('NEXT_PAGE_LABEL');
paginatorIntl.previousPageLabel = this.translate.instant('PREVIOUS_PAGE_LABEL');
paginatorIntl.firstPageLabel = this.translate.instant('FIRST_PAGE_LABEL');
paginatorIntl.lastPageLabel = this.translate.instant('LAST_PAGE_LABEL');
paginatorIntl.getRangeLabel = this.getRangeLabel.bind(this);
return paginatorIntl;
}
private getRangeLabel(page: number, pageSize: number, length: number): string {
if (length === 0 || pageSize === 0) {
return this.translate.instant('RANGE_PAGE_LABEL_1', { length });
}
length = Math.max(length, 0);
const startIndex = page * pageSize;
// If the start index exceeds the list length, do not try and fix the end index to the end.
const endIndex = startIndex < length ? Math.min(startIndex + pageSize, length) : startIndex + pageSize;
return this.translate.instant('RANGE_PAGE_LABEL_2', { startIndex: startIndex + 1, endIndex, length });
}
}
and cz.json
{
"ITEMS_PER_PAGE_LABEL": "Počet řádků:",
"NEXT_PAGE_LABEL": "Další stránka",
"PREVIOUS_PAGE_LABEL": "Předchozí stránka",
"FIRST_PAGE_LABEL": "První stránka",
"LAST_PAGE_LABEL": "Poslední stránka",
"RANGE_PAGE_LABEL_1": "0 z {{length}}",
"RANGE_PAGE_LABEL_2": "{{startIndex}} - {{endIndex}} z {{length}}"
}
Configure ngx-translate in app.module.ts
:
import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core';
const httpLoaderFactory = (http: HttpClient) => new TranslateHttpLoader(http, './assets/i18n/', '.json');
@NgModule({
imports: [
TranslateModule.forRoot({
loader: { provide: TranslateLoader, useFactory: httpLoaderFactory, deps: [HttpClient] }
})
],
providers: [{ provide: LOCALE_ID, useValue: 'cs' }],
bootstrap: [AppComponent]
})
export class AppModule { }
Upvotes: 74
Reputation: 11
A laconic solution to change all labels of MatPaginator.
const rangeLabel: string = 'із';
const itemsPerPageLabel: string = 'Елементiв на сторiнцi:';
const firstPageLabel: string = 'Перша сторінка';
const lastPageLabel: string = 'Остання сторінка';
const previousPageLabel: string = 'Попередня сторінка';
const nextPageLabel: string = 'Наступна сторінка';
const getRangeLabel: (page: number, pageSize: number, length: number) => string = (
page: number,
pageSize: number,
length: number
): string => {
return new MatPaginatorIntl().getRangeLabel(page, pageSize, length).replace(/[a-z]+/i, rangeLabel);
};
export function getPaginatorIntl(): MatPaginatorIntl {
const paginatorIntl: MatPaginatorIntl = new MatPaginatorIntl();
paginatorIntl.itemsPerPageLabel = itemsPerPageLabel;
paginatorIntl.firstPageLabel = firstPageLabel;
paginatorIntl.lastPageLabel = lastPageLabel;
paginatorIntl.previousPageLabel = previousPageLabel;
paginatorIntl.nextPageLabel = nextPageLabel;
paginatorIntl.getRangeLabel = getRangeLabel;
return paginatorIntl;
}
Upvotes: 1
Reputation: 355
Following the current Angular Material documentation (10.2.0) to modify the labels and text displayed, create a new instance of MatPaginatorIntl and include it in a custom provider. You have to import MatPaginatorModule (you would need it anyway to display paginator component)
import { MatPaginatorModule } from '@angular/material/paginator';
and in your component (where you are using paginator) you could use it in following way:
constructor(private paginator: MatPaginatorIntl) {
paginator.itemsPerPageLabel = 'Your custom text goes here';
}
Upvotes: 0
Reputation: 177
For angular 9.0.0, if you are using i18n package, you can do
require: ng add @angular/localization
Create a file called my-paginator-intl.ts
import { MatPaginatorIntl } from '@angular/material/paginator'
const matRangeLabelIntl = (page: number, pageSize: number, length: number) => {
if (length === 0 || pageSize === 0) {
return $localize`:@@paginator.zeroRange:0 in ${length}`
}
length = Math.max(length, 0)
const startIndex = page * pageSize
// If the start index exceeds the list length, do not try and fix the end index to the end.
const endIndex = startIndex < length ? Math.min(startIndex + pageSize, length) : startIndex + pageSize
return $localize`:@@paginator.rangeOfLabel:${startIndex + 1} - ${endIndex} in ${length}`
}
export function MyPaginatorIntl() {
const paginatorIntl = new MatPaginatorIntl()
paginatorIntl.itemsPerPageLabel = $localize`:@@paginator.displayPerPage:Items per page`
paginatorIntl.nextPageLabel = $localize`:@@paginator.nextPage:Next page`
paginatorIntl.previousPageLabel = $localize`:@@paginator.prevPage:Prev page`
paginatorIntl.getRangeLabel = matRangeLabelIntl
return paginatorIntl
}
Import to app.modudle.ts
import { MatPaginatorIntl } from '@angular/material/paginator'
import { MyPaginatorIntl } from './shared/paginator-int/my-paginator-intl'
@NgModule({
providers: [
{ provide: MatPaginatorIntl, useValue: MyPaginatorIntl() },
]
})
Copy following to your language xlf file
<trans-unit id="paginator.zeroRange">
<source>0 of <x id="PH" /></source>
<target>0 trong <x id="PH" /></target>
</trans-unit>
<trans-unit id="paginator.rangeOfLabel">
<source><x id="PH" /> - <x id="PH_1" /> of <x id="PH_2" /></source>
<target><x id="PH" /> - <x id="PH_1" /> trong <x id="PH_2" /></target>
</trans-unit>
<trans-unit id="paginator.displayPerPage">
<source>Items per page</source>
<target>Hiển thị/Trang</target>
</trans-unit>
<trans-unit id="paginator.nextPage">
<source>Next page</source>
<target>Trang kế</target>
</trans-unit>
<trans-unit id="paginator.prevPage">
<source>Prev page</source>
<target>Trang trước</target>
</trans-unit>
Upvotes: 9
Reputation: 4964
You can hack your way into MatPaginator._intl
and put your string there using ngx-translate
.
forkJoin({
itemsPerPageLabel: this.translate.get('paginator.itemsPerPageLabel'),
nextPageLabel: this.translate.get('paginator.nextPageLabel'),
previousPageLabel: this.translate.get('paginator.previousPageLabel'),
firstPageLabel: this.translate.get('paginator.firstPageLabel'),
lastPageLabel: this.translate.get('paginator.lastPageLabel'),
}).subscribe(values => {
this.paginator._intl.itemsPerPageLabel = values.itemsPerPageLabel;
this.paginator._intl.nextPageLabel = values.nextPageLabel;
this.paginator._intl.previousPageLabel = values.previousPageLabel;
this.paginator._intl.firstPageLabel = values.firstPageLabel;
this.paginator._intl.lastPageLabel = values.lastPageLabel;
// 1 – 10 of 100
// https://github.com/angular/components/blob/master/src/material/paginator/paginator-intl.ts#L41
this.paginator._intl.getRangeLabel = (page: number, pageSize: number, length: number): string => {
length = Math.max(length, 0);
const startIndex = page * pageSize;
const endIndex = startIndex < length ? Math.min(startIndex + pageSize, length) : startIndex + pageSize;
return this.translate.instant('paginator.getRangeLabel', {
startIndex: startIndex + 1,
endIndex,
length,
});
};
// Otherwise, the paginator won't be shown as translated.
this.dataSource.paginator = this.paginator;
});
Upvotes: 3
Reputation: 1167
this.dataSource.paginator._intl.itemsPerPageLabel = "Your string here";
this worked in latest angular8 + material8;
Upvotes: 2
Reputation: 6666
For a quick and dirty solution use this.paginator._intl property.
In my ...component.ts
I have:
@ViewChild(MatPaginator) paginator: MatPaginator;
ngOnInit() {
...
this.paginator._intl.itemsPerPageLabel = 'My translation for items per page.';
...
}
Upvotes: 25