Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular UI Bootstrap datepicker, callback when view changes

I use the Angular UI Bootstrap, both the latest versions.

I would love to have a callback when my view changes, so i.e. when I switch from May to June. I need this because of the following scenario:

My datepicker shows available and unavailable dates with the customClass function. I fetch all availabilities of the current month, but when I click next or previous, I don't have any callback to fetch the new availabilities.

Also, I don't want an asynchronous call 42 times (one for every class) because you will also get lots of timing issues in de datepicker. I hope someone knows a way to achieve this, I've searched very long for a solution now.

My HTML:

<div class="input-group">
      <span class="input-group-addon" ng-click="vm.OpenDatepicker($event,'1')"><i class="ti-calendar"></i></span>
      <input type="text" class="form-control" datepicker-options="dpOptions" readonly style="cursor:pointer; background-color:white;"
             uib-datepicker-popup="dd-MMMM-yyyy" min-date="minDate" show-weeks="true" ng-model="selectedDate"
             is-open="vm.$scope.datepickers[1]" show-button-bar="false" ng-click="vm.OpenDatepicker($event,'1')" />
</div>

In the $scope.dpOptions (DatePicker Options) I have defined what the custom classes need to be:

$scope.dpOptions.customClass= function (data) {
//Here are my availabilities of the first month fetched
//When I change the month in my view, I first want to have the other availabilities 
//so I can return the new red/green classes
};
like image 347
Jason van der Zeeuw Avatar asked May 18 '16 07:05

Jason van der Zeeuw


1 Answers

My colleague found a solution using an angular $provide.decorator function! This will add some additional features to any existing directive.

$provide.decorator('uibDatepickerDirective', function ($delegate) {
        var directive = $delegate[0];
        var directiveCompile = directive.compile;

        directive.compile = function () {
            var link = directiveCompile.apply(this, arguments);

            return function (scope) {
                link.apply(this, arguments);

                var oldMove = scope.move;
                scope.move = function (direction) {
                    oldMove.apply(this, arguments);
                    scope.$emit('datepicker.monthChanged', this.rows);
                }
            }
        };
        return $delegate;
    });

To call a function now I can add this to any controller with a datepicker:

$scope.$on('datepicker.monthChanged', function (event, rows) {

            let startDate = rows[0][0].date;
            let endDate = rows[5][6].date;
            //Do anything you want!
            //To add customClass, every column has a customClass attribute you can set.

        });
like image 62
Jason van der Zeeuw Avatar answered Oct 19 '22 16:10

Jason van der Zeeuw