Search code examples
angularjsangularjs-material

Format date in Angular JS material using model possible?


Hello I found this on stackoverflow

Change format of md-datepicker in Angular Material

I was able to format date using this mark up:

.module("myApp", ['ngMaterial'])
   .config(function ($mdDateLocaleProvider) {
        $mdDateLocaleProvider.formatDate = function (date) {
         return date ? moment(date).format('DD/MM/YYYY') : '';
    };
 })

Is it possible to format the date using a property instead of static string? Something like this:

return date ? moment(date).format($scope.format) : '';

Thanks.


Solution

  • It's possible with a trick, by using md-date-locale attributes.

    html:

    <md-datepicker ng-model="myDate" md-date-locale="locale"></md-datepicker>
    

    Controller:

    $scope.format = 'L';
    $scope.locale = {
      formatDate: function(date) {
        var m = moment(date);
        return m.isValid() ? m.format($scope.format) : '';
      }
    };
    

    Dynamic format:

    if you want to make it dynamic (change format = change datepicker format), you need to rebuild the datepicker, adding a ng-if in the directive is the trick, and then something like:

    $scope.changeFormat = function() {
      $scope.format = 'DD MMMM YYYY';
      $scope.hideDate = true;
      $timeout(function() {
        $scope.hideDate = false;
      });
    };
    

    html:

    <md-datepicker ng-if="!hideDate" ng-model="myDate" md-date-locale="locale"></md-datepicker> 
    

    working plunker: https://embed.plnkr.co/PvmkEhMOORq6LZTr5lJT/


    UPDATE: Multiple datepicker & after $http calls

    With mutiple datepicker rendered by differents format, loaded by $http call, you could accomplish that with this method because every datepicker could have his own configuration by md-date-locale .

    you could for example build a locale by a function:

    function buildLocale(format) {
      return {
        formatDate: function(date) {
          return moment(date).isValid() ? moment(date).format(format) : '';
        }
      }
    }
    

    then call if when building the datepicker:

    $scope.locales = [];
    $http.get('YOUR SERVER API').then(function(data) {
        $scope.datas = data.data;
        angular.forEach($scope.datas, function(item) {
          $scope.locales[item.data] = buildLocale(item.format);
        })
        //this is to build the datepicker only after all locales are built
        $scope.dateLoaded = true;
      });
    

    and your html:

    <div ng-if="dateLoaded"><!-- ng-if="dateLoaded" make it to render only after all locales are built -->
          <div ng-repeat="field in datas">
            <md-datepicker ng-model="models[data]" md-date-locale="locales[field.id]"></md-datepicker>
          </div>
        </div>
    

    This is a working plunker showing this: https://embed.plnkr.co/fyGIC8UPxOsGs3kKlW9z/