Skip to content
This repository has been archived by the owner on May 29, 2019. It is now read-only.

Timestamp treated as invalid model value in datepicker #2345

Closed
oliversalzburg opened this issue Jun 16, 2014 · 20 comments
Closed

Timestamp treated as invalid model value in datepicker #2345

oliversalzburg opened this issue Jun 16, 2014 · 20 comments

Comments

@oliversalzburg
Copy link
Contributor

The datepicker directive says ng-model can be "a number of milliseconds since 01.01.1970". However parseData will not treat such an input as valid.

@bekos
Copy link
Contributor

bekos commented Jun 17, 2014

@oliversalzburg Can you provide a plunker with your issue?

@oliversalzburg
Copy link
Contributor Author

@bekos Yeah, sorry for not providing one earlier. I just modified the demo plunkr: http://plnkr.co/edit/yDcTUvs7H1xkqJ7XWPBq?p=preview

Please note the paragraph indicating "There is an error in your form.". If I set dt to new Date() instead, the paragraph is not shown.

Interestingly, I still see the paragraph if I use $scope.dt = new Date(1234567890000);. So, I don't think parseData not accepting ints actually has anything to do with it.

@krimple
Copy link

krimple commented Jul 22, 2014

This was bugging us in my training class... I used a Date.now() to generate a time, which Angular can process with a {{ myDate | date:'MM/dd/yyyy' }} template. It was a good exercise for our students to solve, but am curious if this is this on deck for a fix soon? I switched to doing new Date() instead which worked for now but it would be nice to be able to handle a timetick version of the date like Angular's filter does.

@shawa8
Copy link

shawa8 commented Aug 6, 2014

+1

@andreacremese
Copy link

I ran into a similar snag with angular + UI-bootstrap to both initialize and style the content of datepicker input at the same time on load in the controller.

Long story short:

  • Initialize as new Date(): the form with datepicker is VALID but datetime styling is NOT APPLIED.
  • Initialize as Date().now: the form with datepicker is NOT VALID but datetime styling is APPLIED.

Noting that Date.new() returns the number of milliseconds from 1970 (not accepted by datetime) and new Date() returns a JS Date Instance (accepted by DateTime, but not styled properly), the solution was to initialize the variable in the scope to an ISO 8601 string:

var date = new Date();  
$scope.boundVariable = date.toISOString();

ISO string is apparently what datetime binds to the $modelValue of the form.

Interestingly, when using new Date() as initializer, the $viewValue and the $modelValue for the form diverged ($viewValue was a time stamp object, $modelValue was the ISO string). The solution (or workaround) basically initializes the $viewValue coherently with the $modelValue.

@nirre7
Copy link

nirre7 commented Nov 17, 2014

+1

2 similar comments
@delwyn
Copy link

delwyn commented Nov 20, 2014

+1

@haoqunjiang
Copy link

+1

@karianna
Copy link
Contributor

Hi @oliversalzburg - is this with both Angular 1.2.x and 1.3.x?

@oliversalzburg
Copy link
Contributor Author

@karianna I haven't tested this since I reported it. We just moved to a different approach. 1.3 wasn't released when I reported it, but I don't see why the behavior would have changed.

@khashayar
Copy link
Contributor

I've added the following line on top of parseDate():

if (angular.isNumber(viewValue)) {
  viewValue = new Date(viewValue);
}

Then it goes through the if/else chain and falls into

} else if (angular.isDate(viewValue) && !isNaN(viewValue)) {

which handles it correctly.

Updated Plunker

As an alternative we can have this check on if/else chain itself but I didn't want to repeat that part of the chain again.

@karianna Please let me know if you're ok with this, so I'll do a pull request for it.

@karianna
Copy link
Contributor

Yes please (and updated/new test as well please).

khashayar added a commit to khashayar/bootstrap that referenced this issue Feb 21, 2015
Accept a number of milliseconds since 01.01.1970 as a valid value
for `ng-model`

Closes angular-ui#2345
khashayar added a commit to khashayar/bootstrap that referenced this issue Mar 8, 2015
Accept a number of milliseconds since 01.01.1970 as a valid value
for `ng-model`:
- change parseDate() to handle timestamp values
- add the test to `datepicker.spec.js`

Closes angular-ui#2345
@danieljsinclair
Copy link

I also ran into this today and patched mine similarly. I'd also like to be able to write the value back as a timestamp rather than a date object. I'd like to see a timestamp mode that treats the model as a number bidirectionally.

@khashayar
Copy link
Contributor

@danieljsinclair Create a directive with the same name as datepickerPopup in your source code:

module.directive('datepickerPopup', function () {
  function link(scope, element, attrs, ngModel) {
    // View -> Model
    ngModel.$parsers.push(function (value) {
      return Date.parse(value);
    });
  }

  return {
    restrict: 'A',
    require: 'ngModel',
    link: link
  };
})

@rvanbaalen
Copy link
Contributor

That is a very solid solution / workaround.


This email was sent from my iPhone and therefore subject to typos and other inaccuracies.

On 10 mrt. 2015, at 21:12, Khashayar Hajian [email protected] wrote:

@danieljsinclair Create a directive with the same name as datepickerPopup in your source code:

module.directive('datepickerPopup', function () {
function link(scope, element, attrs, ngModel) {
// View -> Model
ngModel.$parsers.push(function (value) {
return Date.parse(value);
});
}

return {
restrict: 'A',
require: 'ngModel',
link: link
};
})

Reply to this email directly or view it on GitHub.

@danieljsinclair
Copy link

Interesting. I didn't think of creating a directive with a matching name. I wrote a similar buddy-directive earlier, but this relies on the datepicker dateParser accepting a timestamp;

    /**
     * Treat dates as a numeric Timestamp - for use with angular-ui/bootstrap/datepicker
     * Processes output from the datepicker and converts to a number
     */
    app.directive('dateAsTimestamp', [function() {

    return {
        require: 'ngModel',
        link: function (scope: ng.IScope, elm: ng.IAugmentedJQuery, attrs: ng.IAttributes, ngModel: ng.INgModelController) {                // Process the output from the datepicker
            ngModel.$parsers.push(function (viewValue: string|number|Date) {

                if (angular.isDate(viewValue) && !isNaN(<number>viewValue)) {
                    return viewValue.valueOf();
                }

                // otherwise - do nothing
                return viewValue;
            });
        },
    };

}]);

@wesleycho
Copy link
Contributor

This should now be fixed in master.

@karianna karianna removed the PRs plz! label Mar 22, 2015
@oliversalzburg
Copy link
Contributor Author

Cool! Thanks for taking care of this 👍

@karianna karianna added this to the 0.13.0 milestone Mar 23, 2015
ayakovlevgh pushed a commit to ayakovlevgh/bootstrap that referenced this issue Mar 24, 2015
Accept a number of milliseconds since 01.01.1970 as a valid value
for `ng-model`:
- change parseDate() to handle timestamp values
- add the test to `datepicker.spec.js`

Closes angular-ui#2345
@f1ght4fun
Copy link

Can anyone help as it is still not working for me. I'm on the last 0.14.3 release

"1990-08-01T00:00:00" datetime field is not handled correctly in validator func and returns undefined so on validation form fails

angular.IsNumber and angular.IsDate obv return false when trying to parse this timestamp.

Any ideas?

@icfantv
Copy link
Contributor

icfantv commented Nov 2, 2015

@f1ght4fun, without any further information it's nearly impossible to provide any assistance. My first thought is that you're trying to use a string instead of a Date object for your ng-model on your datepicker.

That said, questions like this are best served by posting them to StackOverflow as documented here. Posting to already closed issues is a good way for stuff to get missed.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.