Angular bootstrap datepicker date format does not format ng-model value

后端 未结 13 1269
借酒劲吻你
借酒劲吻你 2020-12-01 04:24

I am using bootstrap date-picker in my angular application. However when I select a date from that date-picker underlying ng-model that I have bind gets updated I want that

相关标签:
13条回答
  • 2020-12-01 04:38

    All proposed solutions didn't work for me but the closest one was from @Rishii.

    I'm using AngularJS 1.4.4 and UI Bootstrap 0.13.3.

    .directive('jsr310Compatible', ['dateFilter', 'dateParser', function(dateFilter, dateParser) {
      return {
        restrict: 'EAC',
        require: 'ngModel',
        priority: 1,
        link: function(scope, element, attrs, ngModel) {
          var dateFormat = 'yyyy-MM-dd';
    
          ngModel.$parsers.push(function(viewValue) {
            return dateFilter(viewValue, dateFormat);
          });
    
          ngModel.$validators.date = function (modelValue, viewValue) {
            var value = modelValue || viewValue;
    
            if (!attrs.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 = dateParser.parse(value, dateFormat);
              return !isNaN(date);
            }
            else {
              return false;
            }
          };
        }
      };
    }])
    
    0 讨论(0)
  • 2020-12-01 04:39

    I can fix this by adding below code in my JSP file. Now both model and UI values are same.

    <div ng-show="false">
        {{dt = (dt | date:'dd-MMMM-yyyy') }}
    </div>  
    
    0 讨论(0)
  • 2020-12-01 04:41

    The datepicker (and datepicker-popup) directive requires that the ng-model be a Date object. This is documented here.

    If you want ng-model to be a string in specific format, you should create a wrapper directive. 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.github.io/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>

    0 讨论(0)
  • 2020-12-01 04:43

    After checking the above answers, I came up with this and it worked perfectly without having to add an extra attribute to your markup

    angular.module('app').directive('datepickerPopup', function(dateFilter) {
        return {
            restrict: 'EAC',
            require: 'ngModel',
            link: function(scope, element, attr, ngModel) {
                ngModel.$parsers.push(function(viewValue) {
                    return dateFilter(viewValue, 'yyyy-MM-dd');
                });
            }
        }
    });
    
    0 讨论(0)
  • 2020-12-01 04:46

    You may use formatters after picking value inside your datepicker directive. For example

    angular.module('foo').directive('bar', function() {
        return {
            require: '?ngModel',
            link: function(scope, elem, attrs, ctrl) {
                if (!ctrl) return;
    
                ctrl.$formatters.push(function(value) {
                    if (value) {
                        // format and return date here
                    }
    
                    return undefined;
                });
            }
        };
    });
    

    LINK.

    0 讨论(0)
  • 2020-12-01 04:46

    Defining a new directive to work around a bug is not really ideal.

    Because the datepicker displays later dates correctly, one simple workaround could be just setting the model variable to null first, and then to the current date after a while:

    $scope.dt = null;
    $timeout( function(){
        $scope.dt = new Date();
    },100);
    
    0 讨论(0)
提交回复
热议问题