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

Angular 1.3.0 rc0 causes datepicker to display initial date as unformatted string #2659

Closed
byudaniel opened this issue Sep 3, 2014 · 39 comments

Comments

@byudaniel
Copy link

The behavior of $viewValue has changed in this commit. Angular 1.3 rc0 sets $viewValue for dates as a string, so date formatting fails.

@davisford
Copy link

Yea, I'm seeing this as well. Last release I had before upgrading to 1.3 rc0 that I knew worked was angular#1.3.0-build.3102+sha.a9371a1. I tried a few pre-1.3 rc0, but they also weren't working, so I rolled back to that version.

Notably, this also seems to have broken Angular-UI Bootstrap typeahead, with a similar issue $viewValue is broken there (see this issue). In the angular expression thing as thing.name for thing in things, it ends up displaying as [Object object] instead of displaying thing.name.

@bcronje
Copy link

bcronje commented Sep 13, 2014

I have the same problem. Any idea how to fix this?

@bcronje
Copy link

bcronje commented Sep 13, 2014

Here's a fix:

After line https://github.com/angular-ui/bootstrap/blob/master/src/datepicker/datepicker.js#L525 add the following formatter:

ngModel.$formatters.push(function (value) {
  return ngModel.$isEmpty(value) ? value : dateFilter(value, dateFormat);
});

@pkozlowski-opensource Do you have any objections for this? Essentially as @byudaniel indicated, this commit. in AngularJS 1.3 rc0 sets $viewValue for dates as a string. Adding the above $formatter ensures the date is formatted using dateFilter before the default string formatter.

@mgibas
Copy link

mgibas commented Sep 19, 2014

Same issue here - @bcronje fix helps

@DaveWM
Copy link
Contributor

DaveWM commented Sep 23, 2014

Thanks @bcronje, I've submitted a pull request with your fix. I also had to update the $render function, otherwise any changes to the date format are ignored.

@M0nter0
Copy link

M0nter0 commented Sep 24, 2014

Thanks @bcronje, It's working but then I found another issue. When the format changes but not the value, if datefilter() receives an String not matching R_ISO8601_STR it doesn't change the format.

attrs.$observe('datepickerPopup', function(value) {
      dateFormat = value || datepickerPopupConfig.datepickerPopup;
      ngModel.$render();
  });

// Outter change
  ngModel.$render = function() {
    var date = ngModel.$viewValue ? dateFilter(ngModel.$viewValue, dateFormat) : '';
    element.val(date);
    scope.date = parseDate( ngModel.$modelValue );
  };

I've fix it modifying line 549 to pass the object as Date instead of String https://github.com/angular-ui/bootstrap/blob/master/src/datepicker/datepicker.js#L549 from

var date = ngModel.$viewValue ? dateFilter(ngModel.$viewValue, dateFormat) : '';

to

var date = ngModel.$viewValue ? dateFilter(ngModel.$modelValue, dateFormat) : '';

I don't know if this modification could provoke side errors.

@pjtpj
Copy link

pjtpj commented Oct 24, 2014

Fix by @vanHuntsman is working for me on Angular 1.3.0

@sandborg71
Copy link

Does anyone have a clue when there will be an official fix for this very annoying error? Because of stupid limitations in our corporate environment we can not easily change the source datepicker.js as suggested by vanHuntsman... The only solution right now is to roll back angular to an earlier version in our project.

@sandborg71
Copy link

For us the error occurs when changing from 1.3.0-beta.19 to 1.3.0-rc.1 .

@DaveWM
Copy link
Contributor

DaveWM commented Oct 28, 2014

I've found a workaround in this thread (it's actually an issue with AngularStrap, but it looks like the exact same issue as here). 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();
    }
  }
})

This seems to work, see this plunker. All credit goes to @meyerds.

@sandborg71
Copy link

Thanks @DaveWM (and @meyerds) . Your workaround seems to solve the problem!

@malterb
Copy link

malterb commented Oct 28, 2014

@DaveWM and @meyerds. Awesome, thanks!

@tems99
Copy link

tems99 commented Oct 29, 2014

Works for me too...using stable release of 1.3

@court-jus
Copy link

Same here. I've used @DaveWM @meyerds fix

@akupiec
Copy link

akupiec commented Oct 31, 2014

Only @DaveWM fix is working as it should be.
The one @meyerds provided causes parse error upon submit form.
Thanks for your contribution !

@bertrandg
Copy link

@DaveWM thanks for the fix!

@slavafomin
Copy link

Thanks @DaveWM! You saved my day = )

Any ETA for the official fix?

@smarquez1
Copy link

@DaveWM you're the man! Using your fix.

@cnjsstong
Copy link

@DaveWM Thanks so much!

@nespapu
Copy link

nespapu commented Feb 17, 2015

Many thanks to @DaveWM and @meyerds!

@jmayday
Copy link

jmayday commented Feb 17, 2015

Thanks for this code.
If someone could just explain me how exactly this works then it would be great.

So, my question here is why $viewValue gets date like "Feb 17, 2015" and not in specified format? What's a kind of magic for me is that displayed value is in correct format, despite it differs from $viewValue. So, what is the role of $viewValue?

Please have a look at this plunker for example http://plnkr.co/edit/HKALJPWWnpyU8nU8iAvX

EDIT. is it because actually not $viewValue is displayed but element.value? Shouldn't these two values be the same or not necessarily?

@slavafomin
Copy link

Hooray! ))

@karianna karianna modified the milestones: 0.13.0, Backlog Feb 21, 2015
antoinepairet pushed a commit that referenced this issue Feb 21, 2015
Closes #3293
Closes #3279
Closes #2440
Closes #2932
Closes #3074
Closes #2943
Closes #2733

Fixes #3047
Fixes #2659
Fixes #2681
@rvanbaalen
Copy link
Contributor

For anyone still using ~0.12 with Angular 1.3, this is a drop-in fix based on @bcronje's comment

.directive('datepickerPopup', ['datepickerPopupConfig', 'dateParser', 'dateFilter', function (datepickerPopupConfig, dateParser, dateFilter) {
    return {
        'restrict': 'A',
        'require': '^ngModel',
        'link': function ($scope, element, attrs, ngModel) {
            var dateFormat;

            //*** Temp fix for Angular 1.3 support [#2659](https://github.com/angular-ui/bootstrap/issues/2659)
            attrs.$observe('datepickerPopup', function(value) {
                dateFormat = value || datepickerPopupConfig.datepickerPopup;
                ngModel.$render();
            });

            ngModel.$formatters.push(function (value) {
                return ngModel.$isEmpty(value) ? value : dateFilter(value, dateFormat);
            });
        }
    };
}]);

Just create that directive on your own module and you will have a hands-off fix for Angular 1.3 support untill 0.13.0 isn't released.

@neonexus
Copy link

Thank you so much for this simple fix @rvanbaalen!

@rvanbaalen
Copy link
Contributor

You're welcome @neonexus 👍

@h8rry
Copy link

h8rry commented Feb 27, 2015

@rvanbaalen Thanks! Works perfectly.

@BalajiTE
Copy link

Hi rvanbaalen,

Thank you for the fix, but for some reason it's not working for me. Here is how I am using it:

I am using AngularJS 1.3.14, ui.bootstrap.min.js 0.12.1 and ui.bootstrap-tps.min.js 0.12.1 versions

in my HTML, I have the datepicker-popup defined as below:

           <input type="text" class="form-control" name="txtDOB" placeholder="Date of Birth"
                      ng-model="dt1" ng-required="true" ng-change="CalculateAge()"
                      datepicker-popup="dd-MMM-yyyy"
                      is-open="opened" close-text="Close" datepicker-options="dateOptions"
                      show-button-bar="false" datepickerpopup readonly required />

I added the same code given by you as Directive.

When I changed the date on form, ng-model value in ng-change function is still showing the un-formatted long date as string.

Can you tell me what I am doing wrong?

Thanks.

@rvanbaalen
Copy link
Contributor

Please ask your question on StackOverflow. We dont have official Angular 1.3 support at the moment so it can basically be anything why its not working for you. Also, reproduce your problem in a plunkr so others can test and debug it.


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

On 13 mrt. 2015, at 20:43, BalajiTE notifications@github.com wrote:

Hi rvanbaalen,

Thank you for the fix, but for some reason it's not working for me. Here is how I am using it:

I am using AngularJS 1.3.14, ui.bootstrap.min.js 0.12.1 and ui.bootstrap-tps.min.js 0.12.1 versions

in my HTML, I have the datepicker-popup defined as below:

       <input type="text" class="form-control" name="txtDOB" placeholder="Date of Birth"
                  ng-model="dt1" ng-required="true" ng-change="CalculateAge()"
                  datepicker-popup="dd-MMM-yyyy"
                  is-open="opened" close-text="Close" datepicker-options="dateOptions"
                  show-button-bar="false" datepickerpopup readonly required />

I added the same code given by you as Directive.

When I changed the date on form, ng-model value in ng-change function is still showing the un-formatted long date as string.

Can you tell me what I am doing wrong?

Thanks.


Reply to this email directly or view it on GitHub.

@BalajiTE
Copy link

Sure Thank you.

@jmayday
Copy link

jmayday commented Mar 13, 2015

@BalajiTE prepare plunker showing the problem. Recently I successfully applied code fixes to get rid of unformatted initial dates problem. In case you want to look at it here's the plunker: http://plnkr.co/edit/HKALJPWWnpyU8nU8iAvX?p=info

@kodecraft
Copy link

just wanted to feedback that the issue of the datepicker displaying the date unformatted is occurring for angular v1.4 also and davewm's workaround fixes the issue...tks dave+meyerds

@alexbeletsky
Copy link

I'm having this issue on angular 1.4.3 as @kodecraft also mentioned. Are there any ideas how to workaround it?

@EdmundMai
Copy link

Here's my workaround using angular.element. Kinda hacky using jquery but works for me:

View:

    <input type="text"
    class="fromDate"
    datepicker-popup="MM/dd/yyyy"
    ng-model="custom_time_filter_begin"
    ng-focus="showFromCalendar = true"
    is-open="showFromCalendar"
    datepicker-options="datePickerOptions"
    ng-required="true"/>

    <input type="text"
    class="toDate"
    datepicker-popup="MM/dd/yyyy"
    ng-model="custom_time_filter_end"
    ng-focus="showToCalendar = true"
    is-open="showToCalendar"
    ng-required="true"/>
    <input id='custom-duration' class='btn duration-button' type='submit' value='Apply' />

Then in my controller:

  fromDate = $filter('date')($scope.custom_time_filter_begin, "MM/dd/yyyy")
  toDate = $filter('date')($scope.custom_time_filter_end, "MM/dd/yyyy")
  angular.element(".fromDate").val(fromDate)
  angular.element(".toDate").val(toDate)

Hope it helps

@biswajit1
Copy link

I faced a related issue with date picker.
If I select a date from date picker, controller is getting date object.
But, I do not change date using date picker and leave pre-populated date untouched, the controller is getting a string. And $filter('date') of angular was not working on string version of date.
But, good thing is that if we apply new Date() on both string or date, it returns a date.
And, we can apply the result to $filter('date') easily.

s-maheshbabu pushed a commit to s-maheshbabu/time-zone-mate that referenced this issue Jul 25, 2016
mchapman added a commit to forms-angular/forms-angular that referenced this issue Aug 1, 2018
…ctual directive is going in fng-ui-date)
mchapman added a commit to forms-angular/forms-angular that referenced this issue Aug 1, 2018
…ctual directive is going in fng-ui-date)
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