angular-ui / bootstrap

PLEASE READ THE PROJECT STATUS BELOW. Native AngularJS (Angular) directives for Bootstrap. Smaller footprint (20kB gzipped), no 3rd party JS dependencies (jQuery, bootstrap JS) required. Please read the README.md file before submitting an issue!
http://angular-ui.github.io/bootstrap/
MIT License
14.28k stars 6.73k forks source link

Manually typed date and min/max dates #6124

Open yannbertrand opened 8 years ago

yannbertrand commented 8 years ago

Bug description:

This can be demonstrated with the datepicker popup on the angular ui site by following the steps below: http://angular-ui.github.io/bootstrap/#/datepicker

  1. Ensure the min date option is turned on (min date should equal today)
  2. Type in yesterdays date to the datepicker-popup

This shows a red border around the inline datepicker (as it is flagged as ng-invalid-date) however the input box for the datepicker-popup is still valid.

On further investigation it seems that the ng-invalid-date attribute has been set against the popup part of datepicker and not against the input box. This causes issues because firstly, the user cannot see that the element is invalid and secondly the popup does not have a name property so I am unable to check validity from the ng-form (e.g. myForm.myDate.$invalid

Link to minimally-working plunker that reproduces the issue:

See http://stackoverflow.com/questions/23542354/angularui-datepicker-popup-manually-typed-date-and-min-max-dates

Version of Angular, UIBS, and Bootstrap

Angular: 1.5.5

UIBS: 0.14.3

Bootstrap: 3.3.4

icfantv commented 8 years ago

@YannBertrand just a heads up that you entered UIBS 0.14.3 which is quite old.

Are you suggesting we put the red border around the calendar icon as well?

yannbertrand commented 8 years ago

Thanks for the info!

I'm suggesting that min and max dates should be verified when one enter them manually (not only by clicking onto the calendar).

This is what I would expect: uib-date

icfantv commented 8 years ago

I'm not following. Are you saying that when a user enters a date manually, we are not checking it against the min/max date values (if any)?

yannbertrand commented 8 years ago

Absolutely! May it be because of an outdated version?

icfantv commented 8 years ago

That may be, but you're testing against our demo site, which means it's the latest, RELEASED version. I'll have to look and see what's been fixed since.

yannbertrand commented 8 years ago

You can reproduce this on the datepicker popup section.

  1. Click on the "Min date" button to set the min date to yesterday.
  2. Try to select yesterday in the datepicker -> impossible
  3. Change the day manually (inside the input) -> no check that this date is correct
readme42 commented 8 years ago

I confirm: Manually entered (typed) dates in inputs with datepicker-popup, which are outside minDate/maxDate-restrictions, will not mark the input as invalid. (still ng-valid / ng-valid-date instead of ng-invalid / ng-invalid-date).

Can be reprocuded with current documentation as said in the comment above.

@icfantv is still more info needed? There is another issue in which i referenced this one. Seems to be a duplicate.

Dinistro commented 7 years ago

@icfantv I found the cause for this and #6213

The min/max validation is placed in the datepicker and not in the datepickerPopup. Unfortunately the datepicker isn't initialized until the popup is opened (ng-if="isOpen": https://github.com/angular-ui/bootstrap/blob/master/template/datepickerPopup/popup.html#L1).

Additionally the datepicker validation only applies its error on the own ngModuleCtrl and not on the one from the popup (not the same ngModelController).

To fix this, I think we have to add min/max-validation in the popup itself. Perhaps something similar to this:

[
  'minDate',
  'maxDate'
].forEach(function(key){
  $scope.$watch('datepickerOptions.' + key, function(value) {
    minMaxValidation(ngModel.$modelValue);
  });
});

//Perhaps move this to $validators? 
ngModel.$parsers.push(function(date) {
  minMaxValidation(date);
  return date;
});

function minMaxValidation(date) {
  ngModel.$setValidity('dateDisabled', !date || !$scope.isDisabled(date));
}
wesleycho commented 7 years ago

@Dinistro your finding that it is likely due to the ng-if is likely correct - I am noticing some funky behavior in a Plunker I just created here. The initial min date is not being respected.

Dinistro commented 7 years ago

@wesleycho do you suggest to add a validation in the popup, that applies the errors on the input itself (like my sample)?

tonysamperi commented 7 years ago

I noticed the same issue: when typing data manually in input[uib-datepicker-popup] no validation is triggered. Also I'd like to say that the red border is broken (tested on Chrome 56 and Firefox 47) - See screenshot (Chrome) ui_datepicker

tonysamperi commented 7 years ago

Also [uib-datepicker-popup-wrap] is appended after the input [uib-datepicker-popup], instead I think it would be much better to prepend the element. This would allow to create CSS rules with the following selector... [uib-datepicker-popup-wrap] + [uib-datepicker-popup] for example: [uib-datepicker-popup-wrap].ng-invalid + [uib-datepicker-popup]{ border: 1px solid red; }

parker789 commented 7 years ago

I am also having this issue. I'd very much like to be able to use this date picker without having to build custom validation surrounding it. Let me know if there is anything being done on this front if you would.

benmccallum commented 6 years ago

I know it's not great, but it does the trick if anyone needs a solution given this repo is no longer actively worked on. Here's a custom directive I made. Just add valid-date to your <input> and it'll fire the validation and actually add the error to the field's $error collection. Gist here.

Originally needed it for another reason, but trawling the issues here I found this and tested it out on manually typing into the input and it fires. Hopefully it helps some people.