1
votes

I am using angular ui-grid. I want to translate the grid on fly. For example my current language is English. The grid gets rendered in English. Now I switch to french. I want all my menu options to be translated to french. How can I achieve this? This is my link to plunkr.

http://plnkr.co/edit/tpdNYirUEIF3RL0kf2d7?p=preview

Here is my sample code

HTML

<!doctype html>
<html ng-app="app">
  <head>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.js"></script>
    <script src="http://ui-grid.info/docs/grunt-scripts/csv.js"></script>
    <script src="http://ui-grid.info/docs/grunt-scripts/pdfmake.js"></script>
    <script src="http://ui-grid.info/docs/grunt-scripts/vfs_fonts.js"></script>
    <script src="http://ui-grid.info/release/ui-grid-unstable.js"></script>
    <script src="https://rawgithub.com/PascalPrecht/bower-angular-translate/master/angular-translate.min.js"></script>
    <script src="app.js"></script>
    <link rel="stylesheet" href="http://ui-grid.info/release/ui-grid-unstable.css" type="text/css">
    <link rel="stylesheet" href="main.css" type="text/css">
  </head>
  <body>

    <div ng-controller="MainCtrl">
      <select ng-model="lang" ng-options="l for l in langs"></select><br>

      <div ui-i18n="{{lang}}">
         <p>Using attribute:</p>
         <p ui-t="groupPanel.description"></p>
         <br/>
         <p>Using Filter:</p>
         <p>{{"groupPanel.description" | t}}</p>

         <p>Click the header menu to see language. NOTE: TODO: header text does not change after grid is rendered. </p>

         <div ui-grid="gridOptions" class="grid"></div>
      </div>

    </div>
  </body>
</html>

My JS

var app = angular.module('app', ['ngTouch', 'ui.grid', 'pascalprecht.translate']);

app.controller('MainCtrl', ['$scope', 'i18nService', '$http', '$translate','$rootScope', function ($scope, i18nService, $http, $translate,$rootScope) {
    $scope.langs = i18nService.getAllLangs();
    $scope.lang = 'en'

    $scope.gridOptions = {
      columnDefs: [
        { displayName: 'NAME', field: 'name', headerCellFilter: 'translate' },
        { displayName: 'GENDER', field: 'gender', headerCellFilter: 'translate' },
        { displayName: 'COMPANY', field: 'company', headerCellFilter: 'translate', enableFiltering: false  }
      ]
    };
    $http.get('https://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/data/100.json')
    .success(function(data) {
      $scope.gridOptions.data = data;
    });
}]);

app.config(function ($translateProvider) {
  $translateProvider.translations('en', {
    GENDER: 'Gender',
    NAME: 'Name',
    COMPANY: 'Company'
  });
  $translateProvider.translations('de', {
    GENDER: 'Geschlecht',
    NAME: 'Name',
    COMPANY: 'Unternehmen'
  });
  $translateProvider.preferredLanguage('en');
});

The first screenshot refers to default language English. When I change my language to 'de' the grid menu options don't get translated. How can I make this happen? enter image description here

enter image description here

3
After some fiddling I was able to get it working but only by making quite a few changes to their code. In the end it looks like its just simply a bug and not supported right now. Strangely they wrote localization directives to support all the behavior but didn't wire them in yet. If you would like a modified version I am happy to write an awnser but given that the file is 28k lines long I will have to post it on a 3rd party website. - ug_
Okay. Thank you for your input - ASR
I forgot to mention, the localization for the drop downs do exist but only get set on startup and will never be updated after the fact. If you can find out how to force a refresh on the table you might be able to get it to work. However it will likely cause your table state to be wiped. - ug_
Yes. I agree. Refreshing the table will cause the state of the table to be wiped. The docs tells us that the translation happens only when the grid renders. Not sure if its possible to refresh the grid without losing its state. - ASR

3 Answers

1
votes

To translate the Grid on the fly if you are using "Angular Translate", you should only refresh the Grid language when the angular-translate's event "$translateChangeSuccess" get fired like below:

// Get Fired when you change language using angular-translate
$rootScope.$on('$translateChangeSuccess', function (event, a) {
    $scope.language = $translate.proposedLanguage() || $translate.use();
    i18nService.setCurrentLang($scope.language); // Refresh the grid language
});

Do not forget to inject $rootScope and i18nService.

1
votes

I needed to translate on the fly (without page refresh) those custom menu items too as well as "items per page" and such in the pager.

I also wrote an hack/workaround directly in the ui-grid source code so sharing if it might help someone else, at least until there will be an official patch.

  • first at grid definition a new event to handle language changed on the fly (for example via angular dynamic locale):

     onRegisterApi: function(gridApi) {
    
         gridApi.registerEvent('language', 'changed');
         gridApi.language.on.changed($scope, function(language) {
    
               $rootScope.$gridLanguage = language;
    
         });
    
  • then in a controller after language changed raise that event (in my case on $localeChangeSuccess from angular dynamic locale) :

    $scope.$on('$localeChangeSuccess', function (e, locale) {
    
        $scope.$View.GridApi.language.raise.changed(locale);
    
    });
    
  • and here the hacks, where the texts need a refresh, for example adding in uiGridColumnMenu directive link function:

    $scope.$watch('$parent.$root.$gridLanguage', function () {
         if ($scope.$parent.$root.$gridLanguage !== undefined) {
             $scope.menuItems = uiGridColumnMenuService.getDefaultMenuItems($scope);
        }
    });
    
  • or the same for uiGridPager:

    $scope.$watch('$parent.$root.$gridLanguage', function () {
    
        if ($scope.$parent.$root.$gridLanguage !== undefined) {
            $scope.sizesLabel = i18nService.getSafeText('pagination.sizes');
            $scope.totalItemsLabel = i18nService.getSafeText('pagination.totalItems');
            $scope.paginationOf = i18nService.getSafeText('pagination.of');
            $scope.paginationThrough = i18nService.getSafeText('pagination.through');
        }
    
    });
    
0
votes

Working Plnkr

Add following method in controller:

  $scope.changeLanguage = function (key) {
    $translate.use(key);
  };

Call this method with ng-change:

<select ng-model="lang" ng-options="l for l in langs" ng-change="changeLanguage(lang)"></select>