2

I am using angularjs, angular bootstap (this one) and their datepicker to enter date.

<input type="text" datepicker-popup="dd.mm.yyyy" ng-model="dt" datepicker-options="dateOptions" ng-required="true">

I want to be able to change date selected by datepicker manually. For example, I picked 07.09.2013 in datepicker and I want to change it to 07.09.2012. To do this, I click in my input and hit backspace to remove last digit 3 and put there 2. The problem is that when I do this, my ng-model becomes a string from a Date object and datepicker does not catch new date. You can try to do this on angular bootstap page (using firefox).

I understand that it is normal behavior because of input type text, which indicates browser that user can put there any text he want, and ng-model directive, because this is how it works. But is there a workaround for this problem? I thought that I need to monitor my ng-model using ng-change or $watch and convert it to a Date object using libraries mentioned here (I can't use Date.parse() because my date format is not valid for this function).

My question is: are there any different solution to this problem? Any config flags or something angular-specific?

Community
  • 1
  • 1

3 Answers3

2

as far as I know, this behavior is well known by the community.

There might be a possible solution/workaround described by wemove on this site, have not tried it though but it looks promising.

Another possibility is to just use the underlying jquery datepicker directly, which (afaik) is wrapped by the angular directive. That's the way I do it for my project since i need to provide both, datepicker and manual input.

I've made a plnkr here, it's ugly but it works, i.e. you can either use the datepicker or enter the value manually.

Seb

Community
  • 1
  • 1
SebastianRiemer
  • 1,495
  • 2
  • 20
  • 33
2

The date-picker-popup directive formats output according to the format string you specify, however, it does not parse the value that you enter directly into the input element. To do that you currently have to write your own parse. Here's an example of one I use:

evsDirectives.directive('dateParser', function () {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, element, attrs, ctrl) {
            if (!ctrl)
                return;

            ctrl.$parsers.unshift(function (data) {
                // convert data from view format to model format
                return this.parseEuropeanShortDate(data);
            });
        }
    };

    //parses a date in dd/MM/yyyy format
    //returns the input value if not a valid date
    parseEuropeanShortDate: function (d) {
        if (this.isDate(d)) {
            return d;
        }
        else {
            var fragments = d.split('/');
            var result = new Date(Date.UTC(fragments[2], fragments[1] - 1, fragments[0])); // converted
            return (this.isValidDate(result)) ? result : d;     
        }
    }

});

You then apply it to your date-picker-popup input element:

<input type="text" datepicker-popup="dd.mm.yyyy" ng-model="dt" datepicker-options="dateOptions" ng-required="true" date-parser>
Paul Taylor
  • 5,651
  • 5
  • 44
  • 68
1

The simplest way:

  1. Add ng-change="onChange()" in your input tag

    <input type="text" datepicker-popup="dd.mm.yyyy" ng-model="dt" datepicker-options="dateOptions" ng-required="true" ng- change="onChange()">

  2. Implement onChange() method:

    $scope.onChange = function () { $scope.dt = $filter('date')($scope.dt, 'dd.mm.yyyy'); };

Durgpal Singh
  • 11,481
  • 4
  • 37
  • 49