saibot
saibot

Reputation: 435

AG-Grid: Translate headerName with ngx-translate (angular)

We are using Angular to visualise an AG grid. We want the headers of the ag grid to be translated in the language of the user.

Ag grid code:

<ag-grid-angular class="ag-theme-material" [rowData]="productionOrders">
  <ag-grid-column [headerName]="'ORDERS.GRID.EntryCode' | translate" field="entry"></ag-grid-column>
  <ag-grid-column [headerName]="ORDERS.GRID.EntryDescription" field="entryDescription"></ag-grid-column>
</ag-grid-angular>

The same way we can translate a value on our html page itself:

<span>{{ 'ORDERS.Status' | translate}}</span>

I noticed, when the translations are being loaded, ag grid does not notice when the translations are loaded. The value on the html page itself however gets translated.

Extra info: The translate pipe of ngx-translate is an "impure" pipe, which means its value can change (eg. when all translations are loaded)

The same way, when using a headerName without a translation, it does not get updated:

Ag grid code:

<ag-grid-angular class="ag-theme-material" [rowData]="productionOrders">
  <ag-grid-column [headerName]="bindedString" field="entry"></ag-grid-column>
</ag-grid-angular>
this.lazyString = 'test-1';
setTimeout(() => {
  this.lazyString = 'test-2';
}, 3000);

The header name is never updated to "test-2"

Upvotes: 6

Views: 10277

Answers (5)

Sivashankar
Sivashankar

Reputation: 554

Another simple solution, which worked for me from the above references

columDef = [
               {
                  field: 'firstname',
                  headerValueGetter: () => translate.instant('fname') // fname is the translation key
               },
               {
                   field: 'lastname',
                   headerValueGetter: () => translate.instant('lname')
               },
           ]
 
 ngOnInit() 
 {
   this.translate.onLangChange.pipe(takeUntil(this.destroy)).subscribe(() => {
         this.gridApi.refreshHeader();
   });
  }

Upvotes: 0

LacOniC
LacOniC

Reputation: 944

Function in Service

  getTr(key: string) {
    return this.translate.instant(key);
  }

Usage in ColumnDefs

  {
    field: 'name', headerName: this.trService.getTr('NAME')
  },

Upvotes: 0

flatbeat
flatbeat

Reputation: 33

If you want to use the solution of TurboYang with async translation loading just add this:

  private destroy = new Subject<void>();

  constructor(private toastService: ToastService, private translate: TranslateService) {
    translate.onLangChange.pipe(takeUntil(this.destroy)).subscribe(() => {
      this.gridApi.refreshHeader();
    });
    translate.onDefaultLangChange.pipe(takeUntil(this.destroy)).subscribe(() => {
      this.gridApi.refreshHeader();
    });
  }

  ngOnDestroy(): void {
    this.destroy.next();
    this.destroy.complete();
  }

Upvotes: 0

TurboYang
TurboYang

Reputation: 61

demo.component.html

<ag-grid-angular style="width: 100%; height: 100%;" class="ag-theme-material" [rowData]="rowData"
    [columnDefs]="columnDefs" (gridReady)="onGridReady($event)" [pagination]="true">
</ag-grid-angular>

demo.component.ts

import { Component } from '@angular/core';
import { ColDef, GridApi } from 'ag-grid-community';
import { TranslateService } from '@ngx-translate/core';

@Component({
  selector: 'app-demo',
  templateUrl: './demo.component.html',
  styleUrls: ['./demo.component.scss']
})
export class DemoComponent {
  private gridApi: GridApi = null;

  public columnDefs: ColDef[] = [
    { headerName: "Code", field: 'code', sortable: true, resizable: true, headerValueGetter: this.localizeHeader.bind(this) },
    { headerName: 'Version', field: 'version', sortable: true, resizable: true, headerValueGetter: this.localizeHeader.bind(this) },
    { headerName: 'IsEnabled', field: 'isEnabled', sortable: true, resizable: true, headerValueGetter: this.localizeHeader.bind(this) }
  ];

  public rowData: any[] = [];

  constructor(private translateService: TranslateService) {
    this.translateService.onLangChange.subscribe(() => {
      this.gridApi.refreshHeader();
    })
  }

  public onGridReady(parameters: any): void {
    this.gridApi = parameters.api;
  }

  public localizeHeader(parameters: ICellRendererParams): string {
    let headerIdentifier = parameters.colDef.field;
    return this.translateService.instant(headerIdentifier);
  }
}

Upvotes: 6

un.spike
un.spike

Reputation: 5113

Header Value Getters

Use headerValueGetter instead of colDef.headerName to allow dynamic header names.

private translator: TranslateService;
...
colDef.headerValueGetter : this.localizeHeader.bind(this)
....
localizeHeader(params){
    let headerIdentifier = params.colDef.field; // params.column.getColId();
    this.translator.get(headerIdentifier).map((res: string) => {
        return res;
    });
}

Sample from doc

{ 
    headerName: "Country", 
    field: "country", 
    width: 120, 
    enableRowGroup: true, 
    enablePivot: true, 
    headerValueGetter: countryHeaderValueGetter 
},

function countryHeaderValueGetter(params) {
    switch (params.location) {
        case 'csv': return 'CSV Country';
        case 'clipboard': return 'CLIP Country';
        case 'toolPanel': return 'TP Country';
        case 'columnDrop': return 'CD Country';
        case 'header': return 'H Country';
        default: return 'Should never happen!';
    }
}

Upvotes: 3

Related Questions