Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable dates using factory response UI Bootstrap Datepicker

I'm trying to disable a date in the UI Bootstrap Datepicker connected to a Google calendar if that dates already have 3 or more events.

Thus far I get the array of events using an Angular Factory like this:

gardenpage.factory('Dates', function($http, $q) {
var deffered = $q.defer();
var data = [];  
var Dates = {};

Dates.async = function() {
   $http.get('http://localhost:7777/events')
   .success(function (d) {
   data = d;
   deffered.resolve();
});
return deffered.promise;
};
Dates.data = function() { return data; };

return Dates;
});

The list of dates needs a bit more preprocessing so I have a function that puts the only dates that have 3 or more entries in a scope-variable:

$scope.occurences = ['2014-07-21','2014-07-28'];

Now finally this is my modified default UI Bootstrap date picker date disable function:

// Disable weekend selection
$scope.disabled = function(date, mode) {

return ( mode === 'day' && ( date.getDay() === 0 || date.getDay() === 6 || 
$scope.date_occurences.indexOf( $filter('date')(date, 'yyyy-MM-dd') ) !== -1 ));
};

It works as expected except for one little quirk, when the "disabled" function is called by the date picker, the array is empty, waiting for the async callback I presume. Which is why it's first as I select a date in the date picker as my dates gets disabled.

So how to get the callback before the date picker disable function is called, or how do I make it wait ? One alternative might be to refresh the Datepicker after the callback has arrived, but I'm not sure if that function exists on the date picker.

like image 879
Andreas Klintberg Avatar asked Nov 11 '22 04:11

Andreas Klintberg


1 Answers

I didn't solve this exactly as stated above but a bit of a workaround:

1. Used a small code that I found in a stack overflow comment http://plnkr.co/edit/Xwq7YtAD6qNHQw1aES3H?p=preview . Which lets you call the Angular-UI Bootstrap Datepicker "refreshView" using a button or other type of action. Basically setting up a new directive

`app.directive('jmDpRefreshView',function() {
   var noop = function(){};
   var refreshDpOnNotify = function (dpCtrl) {
     return function() {
       dpCtrl.refreshView();
     };
   };
return {
  require: 'datepicker',
  link: function(scope,elem,attrs,dpCtrl) {
    var refreshPromise = scope[attrs.jmDpRefreshView];
    refreshPromise.then(noop,noop,refreshDpOnNotify(dpCtrl));
   } 
 };

});`

To call the refreshView functionality

$scope.toggleDisableMode = function() { dateDisableDeferred.notify(new Date().getTime()); };

The function toggleDisableMode can be called using any type of action, for instance using a button to disable dates from the server: "ng-click='toggleDisableMode()'"

Another thing that might help you is either you could preload your Dates from the server

//preload
$scope.dates = disable_dates();

function disable_dates() {
    console.log("disable dates function")
    Dates.async().then(function() {
        $scope.data = Dates.data();
        //do whatever you like with your data
    });
}

Or you could call the ".notify()" for the deferred when the data has been fetched from the server and it will disable when it is done.

    function disable_dates() {
    console.log("disable dates function")
    Dates.async().then(function() {
        $scope.data = Dates.data();
        //console.log($scope.data )
        //do whatever you like with your server data.

        //notice this line, calls the disable function
        dateDisableDeferred.notify(new Date().getTime());
    });
}

This solution is attributed to this question and the comments in there: angular ui datepicker refresh disabled dates

like image 66
Andreas Klintberg Avatar answered Nov 15 '22 12:11

Andreas Klintberg