Angular UI Bootstrap Datepicker - add custom function to template

10,489

Solution 1

I know its not a good idea to make changes in source file. But If you are okay to make changes in ui bootstrap source file yes you can acheive different colors. Here is one I have made.

Below are changes in source.

Date picker template change (datepicker.html)

<tr ng-repeat=\"row in rows\">\n" +
    "      <td ng-show=\"showWeekNumbers\" class=\"text-center\"><em>{{ getWeekNumber(row) }}</em></td>\n" +
    "      <td ng-repeat=\"dt in row\" class=\"text-center\">\n" +
    "        <button type=\"button\" style=\"width:100%;\" class=\"btn btn-default btn-sm\" ng-class=\"{'dt-disabled':dt.disabled,'btn-info': dt.selected,'dt-selected': dt.selected,'dt-available':(dt.verified && dt.available),'dt-verified':dt.verified}\" ng-click=\"select(dt.date)\" ng-disabled=\"dt.disabled\"><span ng-class=\"{'text-muted': dt.secondary}\">{{dt.label}}</span></button>\n" +
    "      </td>\n" +
    "    </tr>\n" +

Date Picker Controller change (DatepickerController)

//Your modification starts
  this.dateVerified = function(date,mode){
      var currentMode = this.modes[mode || 0];
      return ($scope.dateVerified && $scope.dateVerified({date: date, mode: currentMode.name}))
  }

  this.dateAvailable = function(date,mode){
      var currentMode = this.modes[mode || 0];
      return ($scope.dateAvailable && $scope.dateAvailable({date: date, mode: currentMode.name}))
  }
  //your modification end

Date Picker directive change (datepicker)

.directive( 'datepicker', ['dateFilter', '$parse', 'datepickerConfig', '$log', function (dateFilter, $parse, datepickerConfig, $log) {
  return {
    restrict: 'EA',
    replace: true,
    templateUrl: 'template/datepicker/datepicker.html',
    scope: {
      dateDisabled: '&',
      //your modification starts here
      dateVerified:'&',
      dateAvailable:'&',
      //Your modification ends here
    },



   ngModel.$setValidity('date', valid);

    var currentMode = datepickerCtrl.modes[mode], data = currentMode.getVisibleDates(selected, date);
    angular.forEach(data.objects, function(obj) {
      obj.disabled = datepickerCtrl.isDisabled(obj.date, mode);
    });

  //your modification starts here
    //set dateVerfied 
    if(datepickerCtrl.dateVerified){
        angular.forEach(data.objects, function(obj) {
            obj.verified = datepickerCtrl.dateVerified(obj.date, mode);
        });
    }
    //set date availabe
    if(datepickerCtrl.dateAvailable){
        angular.forEach(data.objects, function(obj) {
            obj.available = datepickerCtrl.dateAvailable(obj.date, mode);
        });
    }
    //Your modification ends here
    ngModel.$setValidity('date-disabled', (!date || !datepickerCtrl.isDisabled(date)));

    scope.rows = split(data.objects, currentMode.split);
    scope.labels = data.labels || [];
    scope.title = data.title;

Your code template

<datepicker ng-model="model.selectedDate" ng-click="dateClicked();" date-format="yyyy-MM-dd" date-type="string"  ng-class="{'opacity-2':model.loadingDate}" style="width: 395px;height: 230px;margin:0 auto;" date-disabled="isDateNonAvailableDate(date, mode)" date-verified="dateVerified(date, mode);" date-available="dateAvailable(date, mode);" show-weeks="true" class="well well-sm" close-text="Close"></datepicker>

Your controller

$scope.dateVerified= function(date, mode) {
        return true;

$scope.dateAvailable = function(date, mode) {
         return true; // to get color
     };

Your css

.dt-available{
    color: #fff;
    background-color: green !important;
    border-color: green !important;
}

.dt-disabled{
    color: #fff;
    background-color: red !important;
    border-color: red !important;
}

.dt-selected{
    color: #fff;
    background-color: blue !important;
    border-color: blue !important;
} 

End Result

Solution 2

Angular UI Bootstrap Datepicker has property custom-class in which you can call your function for defining class:

custom-class (date, mode) (Default: null) : An optional expression to add classes based on passing date and current mode (day|month|year).

Share:
10,489
Radek Anuszewski
Author by

Radek Anuszewski

Software developer, frontend developer in AltConnect, mostly playing with AngularJS and, recently, BackboneJS / MarionetteJS. I have a blog on Medium.com, where I am writer in Frontend Weekly.

Updated on June 14, 2022

Comments

  • Radek Anuszewski
    Radek Anuszewski almost 2 years

    I want to specify color of Angular UI date cells, by adding color for cells, so I override default template with something like this:

    <!-- things from pasted default template, here I change something -->
    <!-- btn-danger instead btn-info for clicked date, test if I can change anything-->
    <!-- call to function from my own controller-->
    <button type="button" style="width:100%;" class="btn btn-default btn-sm"
        ng-class="{'btn-danger': dt.selected, active: isActive(dt)}" ng-click="select(dt.date)"
        ng-disabled="dt.disabled" tabindex="-1">
        <span ng-class="{'text-muted': dt.secondary, 'text-info': dt.current,
        'text-success': hasEventsCreatedByUser(dt)}">
        {{dt.label}}</span>
    </button>
    

    And that is (at the moment) function in my testController

    $scope.hasEventsCreatedByUser = function(date){
                return true;
    };
    

    Change from btn-info to btn-danger was quite easy, it's only paste another class:) But I cannot call method from my controller here - is there any solution to enable calling function from my Controllers in Angular UI template or I have to override in some way default DatepickerController?

    More detailed description: user can create an event with specified date. The idea is to, for example, make cell with date in which he created green

    Mock solution found:

    I use "miniController" which I append only on button:

    <button ng-controller="miniController" type="button" style="width:100%;" class="btn btn-default btn-sm" .....
    

    But I know this is only mock not a solution - if anybody has an idea how to figure it out, I will be very happy if decides to help me - thank you in advance!