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

datepicker validation fails on initial model value #4728

Closed
kaoh opened this issue Oct 26, 2015 · 8 comments
Closed

datepicker validation fails on initial model value #4728

kaoh opened this issue Oct 26, 2015 · 8 comments

Comments

@kaoh
Copy link

kaoh commented Oct 26, 2015

I initialize a datepicker in an input field:

<input class="form-control" type="text" id="productionDate" name="productionDate"
                           uib-datepicker-popup="dd-MMMM-yyyy"
                           ng-model="eis.productionDate"
                           is-open="datePickers.productionDate.opened" datepicker-options="dateOptions" required
                           ng-click="openDatePicker($event, 'productionDate')"/>

The initial model value is 2015-09-24T12:00:00+02:00 as a string coming from a backend REST JSON object. datepicker is running this function later:

  function validator(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;
    }
  }

value is initialized with the model value and dateParser.parse(... fails later because it is expecting a dateFormat == dd-MMMM-yyyy which is not the case.

The fix for this is just to switch the first line of this function:

var value = viewValue || modelValue ||;

My fix is to include this directive and overwrite the date validator:

baseDirective.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;
                }
            };
        }
    };
});
@icfantv
Copy link
Contributor

icfantv commented Oct 26, 2015

Apologies, wrong post before. See below.

@kaoh, please do not use the issues forum for support related requests. Rather, please follow the instructions here. The issues forum is reserved for bugs.

If you think you've found a bug, please follow these instructions.

Unfortunately, if you think you have found a bug and do not follow the above instructions within a reasonable amount of time, we will close the issue due to lack of activity.

@kaoh
Copy link
Author

kaoh commented Oct 26, 2015

I actually had no support request, I wanted to file a bug, so it seems to be the right place here. I'm not sure if I have the time to create a demo for the bug. Do you some test cases where the datepicker is tested? In this case it would be easy for me to initialize it with the problematic data and verify my findings or not.

Has changing

var value = modelValue || viewValue;

to

var value = viewValue || modelValue;

any effect? This would already solve the problem.

@icfantv
Copy link
Contributor

icfantv commented Oct 26, 2015

@kaoh, the reason we ask for a working plunker is that we need to see what exactly it is that you are doing and determine whether or not it is a bug or user error. Sometimes we can glean this from what users have entered in their issue and sometimes not.

If you look at the source code for our repo, you will find test files for each component, but before you go down that road, I would encourage you to create a plunker that demonstrates the problem so you're not spinning your wheels unnecessarily. Reading your initial issue again, it sounds like you're trying to set the model as a string rather than a Date object as required (and indicated by the docs).

@kaoh
Copy link
Author

kaoh commented Oct 26, 2015

OK, thanks. This could be the reason. Is there a way to change this behavior, that also a string can be accepted? What I get from the back end is a JSON string, analyzing each object, what field is a date seems to be a manual task, which is cumbersome and can be improved, I have several dozen of date fields. I recently updated angular-ui and I did not had this behavior before AFAIK.

@icfantv
Copy link
Contributor

icfantv commented Oct 26, 2015

@kaoh, that actually used to be the original behavior but we had to change due to numerous cross-browser issues. The two suggestions I've been making to people are:

  1. Just convert from a string to a Date when the object is read, or
  2. If you're sure your dates are all in the same format and your model is reasonably parseable, you can add an HTTP interceptor to convert them on the fly. You can even use our internal dateparser service as a launch point for creating your own date parsing service.

The right/best solution depends on your app however.

@kaoh
Copy link
Author

kaoh commented Oct 26, 2015

Thanks a lot. This should help to get my application running again. Do you think that my fix using a directive and switching var value = viewValue || modelValue; in the validator is also working or does it has some side effects?
Not sure if this is mentioned in a migration log or the release note, but this change is noteworthy.

@RobJacobs
Copy link
Contributor

This scenario has been talked about at length, see closed issues for more info, here are just a few: #4690, #4662, #4554, #4424, #4324. I recall seeing more than 1 directive created to facilitate what you are attempting...

@koh-osug
Copy link

What's the status of changing the line to var value = viewValue || modelValue; instead of

function validator(modelValue, viewValue) {
    var value = modelValue || viewValue;

This works and removes the painful behavior.

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

No branches or pull requests

4 participants