Angular-UI date picker is in an invalid state when the date format is set to 'dM-yyyy' and ng-model with a string value like "2014-08-31T00: 00: 00Z"

I get the date time value from the asp.net mvc controller as "2014-08-31T00: 00: 00Z". When I bind this value to the mypwerck angular -ui date control, it displays as ng-invalid ng-invalid-date.

I get the date format also from the mvc controller, so I am binding the date format as well in my html.

When I debug the ui-bootstrap-tpls.js file (latest version) at line 1807

enter image description here

It always comes as undefined. I have tried so many alternatives, but I cannot succeed. :(

javascript does not convert angular datepicker ui date to UTC correctly

So please give a few thoughts and suggest to me how I can solve this problem.

Thank you and respect, N. Murali Krishna.

+5
source share
5 answers

I had the same problem. The problem is that Angular expects the actual date object, not a string representation of the date. After collecting a bunch of research, I included transformReponse in $ httpProvider, which checks all string objects to see if they can be converted to date, and if they really convert them.

angular.module('test') .config(['$httpProvider', function ($httpProvider) { // ISO 8601 Date Pattern: YYYY-mm-ddThh:MM:ss var dateMatchPattern = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/; var convertDates = function (obj) { for (var key in obj) { if (!obj.hasOwnProperty(key)) continue; var value = obj[key]; var typeofValue = typeof (value); if (typeofValue === 'object') { // If it is an object, check within the object for dates. convertDates(value); } else if (typeofValue === 'string') { if (dateMatchPattern.test(value)) { obj[key] = new Date(value); } } } } $httpProvider.defaults.transformResponse.push(function (data) { if (typeof (data) === 'object') { convertDates(data); } return data; }); }]) 
+10
source

A few notes here:

  • First, the datepicker directive requires the ng-model object to be Date . This is described here .
  • Secondly, the decision sent (and accepted) by the Fourth above is VERY hard because it takes EVERY date string received in the HTTP response and converts it to a Date object if it matches a hard-coded template. It is not flexible and easily verifiable. This will not be the right solution for most people.

If the global date string conversion on your system is correct, the correct Angular is to create a service that does this for you. It leads me to ...

We (Angular UI Bootstrap) have a mechanism for converting date strings to Date objects through the dateParser service. Here you can see the source code here . NB : this service name is becoming obsolete and changed to uibDateParser with the release of 0.14.0.

+4
source

This is the best solution I've found so far:

 .directive('uibDatepickerPopup', function (dateFilter, uibDateParser, uibDatepickerPopupConfig) { return { restrict: 'A', priority: 1, require: 'ngModel', link: function (scope, element, attr, ngModel) { var dateFormat = attr.uibDatepickerPopup || uibDatepickerPopupConfig.datepickerPopup; ngModel.$validators.date = function(modelValue, viewValue) { var value = viewValue || modelValue; if (!attr.ngRequired && !value) { return true; } if (angular.isNumber(value)) { value = new Date(value); } if (!value) { return true; } else if (angular.isDate(value) && !isNaN(value)) { return true; } else if (angular.isString(value)) { var date = uibDateParser.parse(value, dateFormat); return !isNaN(date); } else { return false; } }; } }; }); 
+4
source

I don’t have enough reputation to comment on Chet’s answer, but thanks for making this solution work for me too! I don’t know how your Github managed to flag you in a problem, but I presented the Github problem in the Angular user interface to help others find a solution and hopefully get third-party Angular users to look at it. Thanks again!

https://github.com/angular-ui/bootstrap/issues/4554

+1
source

To use a formatted date string instead of a Date object like ng-model for Angular Datepicker, you need to create a wrapper directive. The wrapper directive will parse your string in a Date object and pass it to datepicker. When you select a date, it is converted from date to string. Here is an example ( Plunker ):

 (function () { 'use strict'; angular .module('myExample', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']) .controller('MyController', MyController) .directive('myDatepicker', myDatepickerDirective); MyController.$inject = ['$scope']; function MyController ($scope) { $scope.dateFormat = 'dd MMMM yyyy'; $scope.myDate = '30 Jun 2017'; } myDatepickerDirective.$inject = ['uibDateParser', '$filter']; function myDatepickerDirective (uibDateParser, $filter) { return { restrict: 'E', scope: { name: '@', dateFormat: '@', ngModel: '=' }, required: 'ngModel', link: function (scope) { var isString = angular.isString(scope.ngModel) && scope.dateFormat; if (isString) { scope.internalModel = uibDateParser.parse(scope.ngModel, scope.dateFormat); } else { scope.internalModel = scope.ngModel; } scope.open = function (event) { event.preventDefault(); event.stopPropagation(); scope.isOpen = true; }; scope.change = function () { if (isString) { scope.ngModel = $filter('date')(scope.internalModel, scope.dateFormat); } else { scope.ngModel = scope.internalModel; } }; }, template: [ '<div class="input-group">', '<input type="text" readonly="true" style="background:#fff" name="{{name}}" class="form-control" uib-datepicker-popup="{{dateFormat}}" ng-model="internalModel" is-open="isOpen" ng-click="open($event)" ng-change="change()">', '<span class="input-group-btn">', '<button class="btn btn-default" ng-click="open($event)">&nbsp;<i class="glyphicon glyphicon-calendar"></i>&nbsp;</button>', '</span>', '</div>' ].join('') } } })(); 
 <!DOCTYPE html> <html> <head> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-animate.js"></script> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-sanitize.js"></script> <script src="//angular-ui.imtqy.com/bootstrap/ui-bootstrap-tpls-2.5.0.js"></script> <script src="example.js"></script> <link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> </head> <body ng-app="myExample"> <div ng-controller="MyController"> <p> Date format: {{dateFormat}} </p> <p> Value: {{myDate}} </p> <p> <my-datepicker ng-model="myDate" date-format="{{dateFormat}}"></my-datepicker> </p> </div> </body> </html> 
+1
source

Source: https://habr.com/ru/post/1233253/


All Articles