How To Change itemsPerPageLabel in mat-paginator in Angular 6+

Viewed 26621

I am using Angular 6.0.3 with Angular Material 7.1.0, I have my paginator in a separate component (that is not the app.component). What I have tried so far:

Created separate ts file called myPagniator.ts:

import {MatPaginatorIntl} from '@angular/material';

export class MyPaginatorLabel extends MatPaginatorIntl {

  itemsPerPageLabel = 'custome_label_name'; // customize item per page label

  constructor() {
    super();
  }
}

In my app.module.ts : I imported both MatPaginatorModule, MatPaginatorIntl from Angular Material. Inside providers array of app.module.ts, I put in MyPaginatorLabel and MatPaginatorIntl.

In the component which is using Angular MatPaginator, I extends MyPaginatorLabel class and have its constructor calls super() method, still it displays default text "itemsPerPage" after all this

What have I done wrong here ?? Can someone give me a bit of hint ?

7 Answers

Create a new TypeScript file and add a function that is exported and returns a MatPaginatorIntl object.

To modify the labels and text displayed, create a new instance of MatPaginatorIntl and include it in a custom provider - Angular Material - Paginator > API

CustomPaginatorConfiguration.ts

import { MatPaginatorIntl } from '@angular/material';

export function CustomPaginator() {
  const customPaginatorIntl = new MatPaginatorIntl();

  customPaginatorIntl.itemsPerPageLabel = 'Custom_Label:';

  return customPaginatorIntl;
}

Then add it to app.module.ts:

import { MatPaginatorIntl } from '@angular/material';
import { CustomPaginator } from './app/CustomPaginatorConfiguration';

@NgModule({
  // ...
  providers: [
    { provide: MatPaginatorIntl, useValue: CustomPaginator() }
  ]
})

You can also set the setting for a particular component like:

import { CustomPaginator } from './CustomPaginator';
import { MatPaginatorIntl } from '@angular/material';
/**
 * @title Paginator
 */
@Component({
  selector: 'your_component',
  templateUrl: 'your_component.html',
  providers: [
    { provide: MatPaginatorIntl, useValue: CustomPaginator() }  // Here
  ]
})

StackBlitz

 @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;

  ngOnInit() {
    this.paginator._intl.itemsPerPageLabel="Test String";

  }

After declaring paginator, this text can be modified in ngOnInit()

Another way to achieve the result.

App and component modules define MatPaginatorIntl as providers

  providers:[
    MatPaginatorIntl
  ]

Import MatPaginatorIntl, declare on the construtor and inside ngOnInit define the next text.

import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';

  constructor(
    public _MatPaginatorIntl: MatPaginatorIntl
  ) { }

  ngOnInit() {
    this._MatPaginatorIntl.itemsPerPageLabel = 'your custom text 1';
    this._MatPaginatorIntl.firstPageLabel = 'your custom text 2';
    this._MatPaginatorIntl.itemsPerPageLabel = 'your custom text 3';
    this._MatPaginatorIntl.lastPageLabel = 'your custom text 4';
    this._MatPaginatorIntl.nextPageLabel = 'your custom text 5';
    this._MatPaginatorIntl.previousPageLabel = 'your custom text 6'; 
  }

A complete exemple with "of" translated based on Prashant Pimpale example

export function CustomPaginator(): MatPaginatorIntl {
  const customPaginatorIntl = new MatPaginatorIntl();

  customPaginatorIntl.itemsPerPageLabel = 'Items par page :';
  customPaginatorIntl.nextPageLabel = 'Page suivante';
  customPaginatorIntl.firstPageLabel = 'Première page';
  customPaginatorIntl.lastPageLabel = 'Dernière page';
  customPaginatorIntl.previousPageLabel = 'Page précédente';
  customPaginatorIntl.getRangeLabel = (page: number, pageSize: number, length: number) => {
    if (length === 0 || pageSize === 0) {
      return `0 à ${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} sur ${length}`;
  };

  return customPaginatorIntl;
}

just set _intl to new MatPaginatorIntl and set properties. Also set mat-paginator id to 'paginator'.

import {MatPaginator, MatPaginatorIntl} from '@angular/material/paginator';

@ViewChild('paginator') set paginator(pager:MatPaginator) {
    if (pager) {
      this.dataSource.paginator = pager;
      this.dataSource.paginator._intl = new MatPaginatorIntl()
      this.dataSource.paginator._intl.itemsPerPageLabel = "bla bla bla";
    }
  }


<mat-paginator #paginator [pageSizeOptions]="[10, 25, 50, 100]"></mat-paginator>

Complete solution based on ngx-translate and Observable so supports switching languages in the app.

Create subclass of MatPaginatorIntl in which you inject TranslateService. In the constructor translate the paginator labels and listen for language changes to trigger the same. The rangeLabel is translated with interpolation of the startIndex, endIndex and length variables.

import {MatPaginatorIntl} from "@angular/material/paginator";
import {TranslateParser, TranslateService} from "@ngx-translate/core";
import {Injectable, OnDestroy} from "@angular/core";
import {Subject} from "rxjs";
import {takeUntil} from 'rxjs/operators';

/* Sources:
https://medium.com/front-dev/translate-your-matpaginator-with-ngx-translate-and-stay-reactive-4c7b145cae9
https://www.mariokandut.com/how-to-translate-matpaginator-angular/
*/
@Injectable()
export class TranslatedMatPaginator extends MatPaginatorIntl implements OnDestroy {

  private unsubscribe: Subject<void> = new Subject<void>();

  private translatedRangeLabel: string = '';

  constructor(private translateService: TranslateService, private translateParser: TranslateParser) {
    super();

    this.translateService.onLangChange
      .pipe(takeUntil(this.unsubscribe))
      .subscribe(() => {
        this.getAndInitTranslations();
      });

    this.getAndInitTranslations();
  }

  ngOnDestroy() {
    this.unsubscribe.next();
    this.unsubscribe.complete();
  }

  getAndInitTranslations() {
    this.translateService.stream([
      'paginator.first.page',
      'paginator.items.per.page',
      'paginator.last.page',
      'paginator.next.page',
      'paginator.previous.page',
      'paginator.range'
    ])
      .pipe(takeUntil(this.unsubscribe))
      .subscribe(translation => {
        this.firstPageLabel = translation['paginator.first.page'];
        this.itemsPerPageLabel = translation['paginator.items.per.page'];
        this.lastPageLabel = translation['paginator.last.page'];
        this.nextPageLabel = translation['paginator.next.page'];
        this.previousPageLabel = translation['paginator.previous.page'];
        this.translatedRangeLabel = translation['paginator.range'];

        this.changes.next();
      });
  }

  getRangeLabel = (page: number, pageSize: number, length: number) => {
    length = Math.max(length, 0);
    const startIndex = page * pageSize;
    const endIndex = startIndex < length ? Math.min(startIndex + pageSize, length) : startIndex + pageSize;

    let translation = this.translateParser.interpolate(this.translatedRangeLabel, {startIndex, endIndex, length});
    if (translation) {
      return translation;
    }

    return this.translatedRangeLabel;
  };
}

In your module code add a provider which basically returns an instance of your custom translated subclass whenever a MatPaginatorIntl instance is required. in app.module.ts or material.module.ts

import {TranslatedMatPaginator} from "./translated-mat-paginator";
...
providers: [
    {provide: MatPaginatorIntl, useClass: TranslatedMatPaginator},
  ]
this.dataSource.paginator._intl.itemsPerPageLabel ='Nombre de Session par page';
Related