loveprogramming
loveprogramming

Reputation: 578

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.

Upvotes: 0

Views: 1141

Answers (2)

Fetrarij
Fetrarij

Reputation: 7326

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/

Upvotes: 3

Maxim Shoustin
Maxim Shoustin

Reputation: 77904

The config is loaded before any controller so you cannot use $scope.

So you can use constant, a.e.:

.constant('Constants', {
    DATE_FORMAT:        'DD/MM/YYYY'
});

Because the constants are fixed, they get applied before other provide methods. See $provide.constant().

Example:

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

Upvotes: 1

Related Questions