0

I'm using Angular Material md-datepicker. The value of ng-model looks something like this: "2017-04-04T22:12:51.000Z" (it's called ISO format or something..)

Well, the question is: How to create a global config, so that all md-datepicker tags always format and parse the ng-model value in a certain format, let's say YYYY-MM-DD?

angular.module('MyApp')
  .controller('AppCtrl', function($scope) {
    $scope.myDate = new Date();

    $scope.minDate = new Date(
      $scope.myDate.getFullYear(),
      $scope.myDate.getMonth() - 2,
      $scope.myDate.getDate());

    $scope.maxDate = new Date(
      $scope.myDate.getFullYear(),
      $scope.myDate.getMonth() + 2,
      $scope.myDate.getDate());    })

.config(function($mdDateLocaleProvider) {
  $mdDateLocaleProvider.parseDate = function(dateString) {
    var m = moment(dateString, 'L', true);
    return m.isValid() ? m.toDate() : new Date(NaN);
  };

  $mdDateLocaleProvider.formatDate = function(date) {
    var m = moment(date);
    return m.isValid() ? m.format('L') : '';
  };
});
<link href="https://material.angularjs.org/HEAD/docs.css" rel="stylesheet"/>
<link href="https://material.angularjs.org/HEAD/angular-material.css" rel="stylesheet"/>


<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular-animate.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular-aria.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular-messages.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular-route.min.js"></script>
<script src="https://material.angularjs.org/HEAD/angular-material.js"></script>
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-114/assets-cache.js"></script>



<div ng-app="MyApp" ng-controller="AppCtrl">
  <md-content>
    <md-datepicker ng-model="myDate" md-placeholder="Enter date"></md-datepicker>
  </md-content>
  
  <big>ng-model value is: <strong>{{myDate}}</strong></big>
</div>
<p>
I want to format it this way: YYYY-MM-DD
</p>

I would appreciate any help!! THANKS!

Beqa
  • 101
  • 2
  • 14
  • 1
    possible duplicate of [change format of md-datepicker in angular material](http://stackoverflow.com/questions/32566416/change-format-of-md-datepicker-in-angular-material) – Felix Haeberle Apr 12 '17 at 23:10
  • As you can see, I've included `$mdDateLocaleProvider.formatDate` in my code. It doesn't change the ng-model format, but modifies the way the date is displayed inside the input tag. – Beqa Apr 12 '17 at 23:17
  • why do you want to change the ng-model format? – Felix Haeberle Apr 12 '17 at 23:25
  • I need to parse the date in php and vice versa. – Beqa Apr 12 '17 at 23:32
  • Well in this case I would suggest to do the parse in php :) [link](http://stackoverflow.com/questions/3106652/php-convert-iso-date-to-more-readable-format) – Felix Haeberle Apr 12 '17 at 23:41
  • I can parse JS date string in PHP, but what about vice versa? I can only send a JS date *string* back to material md-datepicker, while it requires a `new Date()` object instead of a string. So it gives an error -> `Error: The ng-model for md-datepicker must be a Date instance. Currently the model is a: string` – Beqa Apr 13 '17 at 10:05
  • In PHP you can for example use `strtotime()` and in JS see [this question](http://stackoverflow.com/questions/476105/how-can-i-convert-string-to-datetime-with-format-specification-in-javascript) for more info. – Felix Haeberle Apr 13 '17 at 10:37

2 Answers2

0

However, I've fixed my problem by creating a custom directive.

Hope this helps some other developers too.

Yohoo!

angular.module('MyApp')

.controller('AppCtrl', function($scope) {
  $scope.person = {
    name: "John",
    birthDate: "1990-01-01 00:00:00"
  };
})

.directive('mdDatepicker', function () {
  function link(scope, element, attrs, ngModel) {
    var parser = function (val) {
      val = moment(val).format('YYYY-MM-DD hh:mm:ss');
      return val;
    };
    var formatter = function (val) {
      if (!val) return val;
      val = moment(val).toDate();
      return val;
    };
    ngModel.$parsers.push(parser);
    ngModel.$formatters.push(formatter);
  }
  return {
    require: 'ngModel',
    link: link,
    restrict: 'EA',
    priority: 1
  }
});
<link href="https://material.angularjs.org/HEAD/docs.css" rel="stylesheet"/>
<link href="https://material.angularjs.org/HEAD/angular-material.css" rel="stylesheet"/>


<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular-animate.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular-aria.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular-messages.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular-route.min.js"></script>
<script src="https://material.angularjs.org/HEAD/angular-material.js"></script>
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-114/assets-cache.js"></script>



<div ng-app="MyApp" ng-controller="AppCtrl">
  <md-content>
    <md-datepicker ng-model="person.birthDate" md-placeholder="Enter date"></md-datepicker>
  </md-content>
  
  <big>ng-model value is: <strong>{{person.birthDate}}</strong></big>
</div>
Beqa
  • 101
  • 2
  • 14
0

This is an old post but just in case:

The md-datepicker object only accept date object. You can create a temporary date variable for your ng-model and then convert the date variable into a string in the ng-change directive.

<md-datepicker ng-model="tempDate" md-placeholder="Enter date" ng-change="person.birthDate = formatDate(tempDate)"></md-datepicker>

Then in the controller just implement the formatDate() function:

   $scope.formatDate = function (date) {
     return moment(date).format('YYYY-MM-DD hh:mm:ss');
   }

I hope it helps

lordofmax
  • 773
  • 1
  • 7
  • 21