Search code examples
angularjsdatepickerangular-translate

How to translate the input text (datepicker) value dynamically using angular-translate?


I am using angular-translate to provide i18n to my application, I am able to translate labels, button-text etc. properly. The problem I am facing is when I am trying to change the date according to the selected language locale. The date is selected from a date-picker.

the date is selected into an input element:

<input type="text" class="form-control" required="" ng-model="date" placeholder="{{ 'DATE_PLACEHOLDER' | translate }}" translate="{{ 'select_date'|translate:{date:date} }}"/>

the placeholder translation works perfectly, but no change happens to date format when I change the language. I have created a plunkr describing the current scenario.

Plunker Link

Please suggest a way in which I can translate inserted values, or text in forms. Also, I would like to know how to overcome the flicker of key values just before the page is loaded.


Solution

    1. Add Italian locale, I copied it from http://forum.html.it/forum/showthread/t-2912577.html:

      $.fn.datepicker.dates['it'] = {
        days: ["Domenica", "Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato", "Domenica"],
        daysShort: ["Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab", "Dom"],
        daysMin: ["Do", "Lu", "Ma", "Me", "Gi", "Ve", "Sa", "Do"],
        months: ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"],
        monthsShort: ["Gen", "Feb", "Mar", "Apr", "Mag", "Giu", "Lug", "Ago", "Set", "Ott", "Nov", "Dic"],
        today: "Oggi",
        clear: "Cancella",
        weekStart: 1,
        format: "dd/mm/yyyy"
      };
      
    2. Add convert map for language codes from en_EN format to en:

      // language codes convertor map
      var convertorMap = {
        'en_US': 'en',
        'it_IT': 'it'
      };
      
    3. In your language switcher function, remove current datepicker and initialize a new one with new language, make sure to update date in new format as well:

      $scope.switchLanguage = function (key) {
        var dp = $('#datePicker');
        // get current date
        var currentDate = dp.datepicker('getDate');
      
        // update datepicker with new locale
        dp.datepicker('remove');
        dp.datepicker({
          autoclose: true,
          language: convertorMap[key]
        });
        // restore current date according to the new locale
        dp.datepicker('update', currentDate);
      
        $translate.use(key);
      };
      
    4. To show view only when translation is ready, change your wrapper element (I used <body>) to look like:

      <body ng-controller="Ctrl" class="ng-hide" ng-show="showView">
        .....
      </body>
      

      and in your controller:

      // will be fired when the service is "ready" to translate (i.e. loading 1st language)
      $translate.onReady(function () {
        $scope.showView = true;
      });
      
    5. ng-model directive on jQuery datepicker does nothing, so I removed it, and added ng-model update code to initial datepicker function:

      $('#datePicker').datepicker({
        autoclose: true
      })
      // update ng model
      .on('changeDate', function(e) {
        $timeout(function () {
          $scope.date = $('#datePicker').datepicker('getUTCDate');
        });
      });
      

    if you see in the console message like:

    pascalprecht.translate.$translateSanitization: No sanitization strategy has been configured. This can have serious security implications.

    it is said to be fixed in next releases: https://github.com/taigaio/taiga-front/issues/778

    plunker: http://plnkr.co/edit/EGtHPG?p=preview