Attach click event for weekday labels in Angular UI Bootstrap datepicker

I am using Angular UI Bootstrap datepicker with gm.datepickerMultiSelect and I would like to make shortcuts for weekdays by clicks so that I can select all days of the month (for example, on Wednesdays). I can get / calculate all the days of the same day of the week and add them to the selected days area, but since I'm pretty new to the AngularJS and Bootstrap user interfaces, I cannot find the correct way to trigger this click event for shortcuts.

+1
source share
1 answer

Angular UT Bootstrap allows you to override their directive templates. You can create your own template by placing it in a tag <script>with a type text/ng-template.

So, we copy the contents of Angular UI template/datepicker/day.htmland modify it a bit to call a new function selectWeekdayon our weekday ng-click:

<script type="text/ng-template" id="template/datepicker/day.html">
  <table role="grid" aria-labelledby="{{::uniqueId}}-title" aria-activedescendant="{{activeDateId}}">
    <thead>
      <tr>
        <th>
          <button type="button" class="btn btn-default btn-sm pull-left" ng-click="move(-1)" tabindex="-1"><i class="glyphicon glyphicon-chevron-left"></i></button>
        </th>
        <th colspan="{{::5 + showWeeks}}">
          <button id="{{::uniqueId}}-title" role="heading" aria-live="assertive" aria-atomic="true" type="button" class="btn btn-default btn-sm" ng-click="toggleMode()" ng-disabled="datepickerMode === maxMode" tabindex="-1" style="width:100%;"><strong>{{title}}</strong></button>
        </th>
        <th>
          <button type="button" class="btn btn-default btn-sm pull-right" ng-click="move(1)" tabindex="-1"><i class="glyphicon glyphicon-chevron-right"></i></button>
        </th>
      </tr>
      <tr>
        <th ng-if="showWeeks" class="text-center"></th>
        <!-- Added ng-click and style -->
        <th ng-click="selectWeekday(label)" style="cursor:pointer;" ng-repeat="label in ::labels track by $index" class="text-center"><small aria-label="{{::label.full}}">{{::label.abbr}}</small></th>
      </tr>
    </thead>
    <tbody>
      <tr ng-repeat="row in rows track by $index">
        <td ng-if="showWeeks" class="text-center h6"><em>{{ weekNumbers[$index] }}</em></td>
        <td ng-repeat="dt in row track by dt.date" class="text-center" role="gridcell" id="{{::dt.uid}}" ng-class="::dt.customClass">
          <button type="button" style="min-width:100%;" class="btn btn-default btn-sm" ng-class="{'btn-info': 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}">{{::dt.label}}</span></button>
        </td>
      </tr>
    </tbody>
  </table>
</script>

Note . This script tag must be in yours ng-app, otherwise it will be ignored and will not overwrite the original template.

Now we need to change the directive datepickerusing AngularJS decoders to add a function selectWeekday:

angular.module('myApp', [
  'ui.bootstrap',
  'gm.datepickerMultiSelect'
  ])
  .config(function($provide) {
    $provide.decorator('datepickerDirective', function($delegate) {
      var directive = $delegate[0];
      //get a copy of the directive original compile function
      var directiveCompile = directive.compile;

      //overwrite the original compile function
      directive.compile = function(tElement, tAttrs) {
        // call the directive compile with apply to send the original 'this' and arguments to it
        var link = directiveCompile.apply(this, arguments);

        //here where the magic starts
        return function(scope, element, attrs, ctrls) {
          //call the original link
          link.apply(this, arguments);

          scope.selectWeekday = function(label) {
            scope.$emit('datepicker.selectWeekday', label);
          };

        };
      };

      return $delegate;
    });
  })

And listen from the controller datepicker.selectWeekday:

.controller('DateController', function($scope) {

  $scope.$on('datepicker.selectWeekday', function(event, newVal) {
    $scope.selectedWeekday = newVal;
  });

});

Here you can add logic to select days based on a known selected weekday!

plunkr: http://plnkr.co/edit/Ef4gd7SUYMcG05PuvqFh?p=preview

+1

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


All Articles