0

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.

loveprogramming
  • 538
  • 2
  • 5
  • 22

2 Answers2

3

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/

Fetrarij
  • 7,176
  • 3
  • 27
  • 35
  • I just ran into one issue. Is it possible to pass a dateFormat parameter to the $scope.locale function? So I could return something like this: return m.isValid() ? m.format(dateFormat) : ''; – loveprogramming Aug 08 '17 at 23:39
  • 1
    No it's not possible, $scope.locale should be an object which allows for the values from the $mdDateLocaleProvider to be ovewritten. But you can use another function like I did to change this object. What really do you want to accomplish? with a select box for example: https://embed.plnkr.co/vchelyBPAyiWaxlx5ozw/ – Fetrarij Aug 09 '17 at 03:20
  • I am using $http service to get data from the database and build my form. So on page load, the form is already populated with different inputs. That means the format for each datepicker should have been set up by then. No more changes to the date format. Some datepicker needs DD/MM/YYYY and some needs MM/DD/YYYY. Thanks. – loveprogramming Aug 09 '17 at 03:51
  • 1
    using md-date-locale, you could accomplish your need, you could have multiple datepicker with differents format, but with the $http load, you just need to build all datepicker only after the $http request is done. – Fetrarij Aug 09 '17 at 04:56
  • Sorry are you talking about this? . It doesn't work for me. Yes, I built all datepickers after $http is completed. field.format is actually what I want to be bound to the locale. Thanks – loveprogramming Aug 09 '17 at 05:24
  • 1
    I updated the answer, and I added a working plunker which is close to your issue. – Fetrarij Aug 09 '17 at 05:34
1

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) : '';
        };
    })
Maxim Shoustin
  • 77,483
  • 27
  • 203
  • 225