Angular - ui-bootstrap - datepicker - Is there a way to detect when a month has changed?

I would like to set the date in the 1st of the selected months when it changed.

Is there a way to track the click event on the buttons of the month?

Tia Sam

+6
source share
4 answers

In the Datepicker area, there is a 'activeDateId' property that you can see. It changes when you switch months.

I think the best way is to create a β€œdecorator” in the datepicker directive so that you can add functionality to it. You can access your scope if you override the compilation function.

You execute this in the module.config function:

$provide.decorator('datepickerDirective', function($delegate) { var directive = $delegate[0]; /* Override compile */ var link = directive.link; directive.compile = function() { return function(scope, element, attrs, ctrl) { link.apply(this, arguments); scope.$watch('activeDateId', function() { console.log('switched'); }); } }; return $delegate; }); 

EDIT

I ran into a problem similar to a code where, if you switch the month and 2 months have their first date on the same day, the $ clock will not work. You can get around this by looking at the value of the "activeDate" property in the Datepicker controller:

  scope.$watch(function() { return ctrl.activeDate.getTime(); }, function() { console.log('switched'); }); 
+4
source

Unfortunately, the datepicker directive datepicker not have a binding for tracking month / year changes. This is what I came up with as a job.

In html ...

 <datepicker month-changed="changeMonth($month, $year)" /> 

In the controller ...

 $scope.changeMonth = function(month, year) { console.log(month, year); // set your date here if you need to // in my case, i needed to request some results via ajax }; 

Decorator

 app.config(function($provide) { $provide.decorator('datepickerDirective', function($delegate) { var directive = $delegate[0], link = directive.link; angular.extend(directive.scope, { 'monthChanged': '&' }); directive.compile = function() { return function(scope, element, attrs, ctrl) { link.apply(this, arguments); scope.$watch(function() { return ctrl[0].activeDate.getTime(); }, function(newVal, oldVal) { if (scope.datepickerMode == 'day') { oldVal = moment(oldVal).format('MM-YYYY'); newVal = moment(newVal).format('MM-YYYY'); if (oldVal !== newVal) { var arr = newVal.split('-'); scope.monthChanged({ '$month': arr[0], '$year': arr[1] }); } } }); }; }; return $delegate; }); }); 

Another decorator

Here is another decorator that also works, but is probably a bit more resource intensive. Everything I do here overrides the isActive() method already used in the directive, so the method is called instead. I just post this as an example of possible ways to circumvent some limitations in third-party directives. I do not necessarily recommend this solution.

 app.config(function($provide) { $provide.decorator('datepickerDirective', function($delegate) { var directive = $delegate[0], link = directive.link; angular.extend(directive.scope, { 'monthChanged': '&' }); directive.compile = function() { return function(scope, element, attrs, ctrl) { link.apply(this, arguments); var activeMonth, activeYear, activeFn = scope.isActive; scope.isActive = function(dateObj) { if (scope.datepickerMode == 'day' && !dateObj.secondary) { var oldMonth = activeMonth, oldYear = activeYear, newMonth = dateObj.date.getMonth() + 1; newYear = dateObj.date.getFullYear(); if (oldMonth !== newMonth || oldYear !== newYear) { activeMonth = newMonth; activeYear = newYear; scope.monthChanged({ '$month': newMonth, '$year': newYear }); } } activeFn(dateObj); }; }; }; return $delegate; }); }); 
+4
source

Put $ watch on the model the date is attached to:

 <datepicker ng-model="data.date" min-date="minDate" show-weeks="true" class="well well-sm"></datepicker> $scope.$watch('data.date', function(){ //date has changed }); 
0
source

I had the same problem when I tried to install the ng model on the first day of January when they choose the year. The answers from @Rob and @spongessuck really helped me. This is how I solved it. Whenever you select a year or month, the activeDate variable activeDate . I use $setViewValue to set the model to activeDate by observing the datepickerMode variable, which changes whenever you select a year, month or date.

`

 app.config(function ($provide) { $provide.decorator('datepickerDirective', function ($delegate) { var directive = $delegate[0], link = directive.link; directive.compile = function () { return function (scope, element, attrs, ctrl) { link.apply(this, arguments); scope.$watch('datepickerMode', function (newValue, oldValue) { if (newValue!=oldValue && newValue == 'month') { ctrl[1].$setViewValue(ctrl[0].activeDate); } }); }; }; return $delegate; }); }); 

`

Hope this helps someone.

0
source

Source: https://habr.com/ru/post/978186/


All Articles