Skip to content

Instantly share code, notes, and snippets.

@cgmartin
Last active May 21, 2018 21:42
Show Gist options
  • Save cgmartin/3daa01f910601ced9cd3 to your computer and use it in GitHub Desktop.
Save cgmartin/3daa01f910601ced9cd3 to your computer and use it in GitHub Desktop.
Send an event to refresh view of ui-bootstrap datepicker
/**
* Decorates the ui-bootstrap datepicker directive's controller to allow
* refreshing the datepicker view (and rerunning invalid dates function)
* upon an event trigger: `$scope.$broadcast('refreshDatepickers');`
*
* Works with inline and popup. Include this after `ui.bootstrap` js
*/
angular.module('ui.bootstrap.datepicker')
.config(function($provide) {
$provide.decorator('datepickerDirective', function($delegate) {
var directive = $delegate[0];
var link = directive.link;
directive.compile = function() {
return function(scope, element, attrs, ctrls) {
link.apply(this, arguments);
var datepickerCtrl = ctrls[0];
var ngModelCtrl = ctrls[1];
if (ngModelCtrl) {
// Listen for 'refreshDatepickers' event...
scope.$on('refreshDatepickers', function refreshView() {
datepickerCtrl.refreshView();
});
}
}
};
return $delegate;
});
});
@haskelcurry
Copy link

@oomkoos, @spirau

I suppose that the cause of the problem here is the one-time binding (ng-repeat="label in ::labels track by $index").
So that the day names get refreshed only when the ng-switch-when condition gets changed, as @spirau mentioned. So, the ugly workaround would be to force this change automatically:

scope.$on('$localeChangeSuccess', function () {
    const mode = scope.datepickerMode;
    scope.datepickerMode = '';
    scope.$$postDigest(() => {
        scope.datepickerMode = mode;
    });
    datepickerCtrl.refreshView();
});

It will flicker when opened, though, but that's not critical for me. The datepicker is always closed when the locale gets changed.

If anyone else figured out a better solution please let us know!
Cheers.

@nlitwin
Copy link

nlitwin commented May 21, 2018

If you're using a later version of Angular UI Bootstrap, replace:
$provide.decorator('datepickerDirective', function($delegate) {
with
$provide.decorator('uibDatepickerDirective', function($delegate) {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment