Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angular 1.3.0 and input[type=string]

We recently updated our application to use the latest angular version, from a version to before 1.3.0 to 1.5.0. Apparently we now bump into a breaking change introduced in 1.3.0:

https://github.com/angular/angular.js/issues/9218

We had a custom directive that enabled us to use the pikaday date picker:

module.directive('pikaday', function () {
    return {
        require: 'ngModel',
        link: function preLink(scope, element, attrs, controller) {
            var $element = $(element),
                momentFormat = 'DD/MM/YYYY',
                year = new Date().getFullYear();

            // init datepicker
            var picker = new Pikaday(
                {
                    field: document.getElementById(attrs.id),
                    firstDay: 1,
                    format: momentFormat,
                    minDate: new Date((year - 1) + '-01-01'),
                    maxDate: new Date((year + 1) + '-12-31'),
                    yearRange: [year - 1, year + 1],
                    onSelect: function (date) {
                        controller.$setViewValue(date);
                    },
                    defaultDate: scope.$eval(attrs.ngModel), // require: 'ngModel'
                    setDefaultDate: true
                });

            // format model values to view
            controller.$formatters.unshift(function (modelValue) {
                var formatted = (modelValue)
                    ? moment(modelValue).format(momentFormat)
                    : modelValue;
                return formatted;
            });

            // parse view values to model
            controller.$parsers.unshift(function (viewValue) {
                if (viewValue instanceof Date) {
                    return viewValue;
                }
                else {
                    return moment(viewValue, momentFormat).toDate();
                }
            });
        }
    };
})

This used to work fine, but now after binding a form that has this control, my scope value is suddenly changed from a Date object to a string (without ever interacting with the control!) The funny thing is that this happens without the formatter or parsers ever being called. So it looks like angular just decides to change the scope value just because it is being bound a an input of type "text", even if the value in the input is never touched.

I dont want to use input[type=text] because i dont want the browser to force its own handling of dates.

If my formatter/parser would be called i would know how to work around this, but this has me puzzled.

I could just display a date in a span and have a button the user could click to spawn the pikaday plugin, but i would prefer the behavior to stay as is ...

like image 567
Davy Avatar asked Mar 16 '16 10:03

Davy


1 Answers

Have you seen this workaround from https://github.com/angular-ui/bootstrap/issues/2659 ?

All you have to do is add a directive:

directive('datepickerPopup', function (){
  return {
    restrict: 'EAC',
    require: 'ngModel',
    link: function(scope, element, attr, controller) {
    //remove the default formatter from the input directive to prevent conflict
    controller.$formatters.shift();
   }
 }
})

Work around removes the not so nice working formatter introduced by the 1.3.0 version and thus resolves the issue with it.

This fix should make it as it is widely thanked in the github thread.

like image 69
mico Avatar answered Nov 09 '22 23:11

mico