Angular UI Datepicker Limiting Days per month

后端 未结 2 442
予麋鹿
予麋鹿 2021-01-18 17:53

I am using using the angular datepicker:

http://angular-ui.github.io/bootstrap/#/datepicker

Currently it is hardcoded to display 42 days or 6 w

相关标签:
2条回答
  • 2021-01-18 18:30

    Well, i represent ADMdtp module. It's pure AngularJs dateTimePicker with disabling pattern and other lots of greate options:

    • completely synced with ngModel, so no need to destroy or manulay update dateTimePicker.
    • advance range picker; make as many dateTimePicker as you want related together, and again no need to destroy or manualy update each dateTimePicker.
    • disabing pattern; so easily you can disable any day(s) in week or month, like all weekends.
    • transition on changing days. (of curse you can disable it in options)
    • get full date details like date in UNIX format, Date format and year, month, day, hour and minute separately and ... by full-data attribute.
    • ...

    <adm-dtp ng-model="date" full-data="date_full" options="disabled:['2016/1/20', '!i&i+1', '15d+2']"></adm-dtp>

    0 讨论(0)
  • 2021-01-18 18:37

    You should be able to wrap _refreshView within a new compile function wrapping the old link function, if you use decorator. Within your ctrl._refreshView wrapper, you can do something like:

    directive.compile = function() {
      return function(scope, element, attrs, ctrl) {
        link.apply(this, arguments);
    
        var _refreshView = ctrl._refreshView;
        ctrl._refreshView = function() {
          _refreshView.apply(this, arguments);
          removeAnySecondaryOnlyRows(scope.rows);
        };
    
        removeAnySecondaryOnlyRows(scope.rows);
      };
    };
    

    And:

    //Remove any rows that contain only 'secondary' dates (those from other months)
    function removeAnySecondaryOnlyRows(rows) {
      for (var i = 0; i < rows.length; i++) {
        var row = rows[i],
          areAllSecondary = false;
    
        //check the first and the last cell's .secondary property
        areAllSecondary = row[0].secondary && row[(row.length - 1)].secondary;
    
        if (areAllSecondary) {
          rows.splice(i, 1);
          i--;
        }
      }
    }
    

    And all together as a functioning snippet, including a custom template and some css to hide the 'secondary' days (those from a different month):

    (function() {
      "use strict";
    
      angular.module('myApp', ['ui.bootstrap'])
        .config(['$provide', Decorate])
        .controller("MainController", ['$scope', MainController]);
    
      function Decorate($provide) {
    
        //fix for Datepicker 'day mode' to show only rows with days from the current month
        $provide.decorator('daypickerDirective', ['$delegate', daypickerDirectiveDecorator]);
    
        function daypickerDirectiveDecorator($delegate) {
          var directive = $delegate[0],
            link = directive.link;
    
          // custom html template:
          directive.templateUrl = "common/directives/uiBootstrapDatepickerDay.tpl.html";
    
          directive.compile = function() {
            return function(scope, element, attrs, ctrl) {
              link.apply(this, arguments);
    
              var _refreshView = ctrl._refreshView;
              ctrl._refreshView = function() {
                _refreshView.apply(this, arguments);
                removeAnySecondaryOnlyRows(scope.rows);
              };
    
              removeAnySecondaryOnlyRows(scope.rows);
            };
          };
    
          return $delegate;
        }
    
        //Remove any rows that contain only 'secondary' dates (those from other months)
        function removeAnySecondaryOnlyRows(rows) {
          for (var i = 0; i < rows.length; i++) {
            var row = rows[i],
              areAllSecondary = false;
    
            //check the first and the last cell's .secondary property
            areAllSecondary = row[0].secondary && row[(row.length - 1)].secondary;
    
            if (areAllSecondary) {
              rows.splice(i, 1);
              i--;
            }
          }
        }
      }
    
      function MainController($scope) {
        $scope.dt = new Date();
      }
    })();
    /*
    Example of hiding days from other months:
    We've put a class of 'datepicker' on the element loading the datepicker directive,
    and we've customised the day template to add an 'invis' class to the day's button if
    it's a 'secondary' day (a day from another month).
    */
    
    .datepicker .invis {
      visibility: hidden;
    }
    <link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.28/angular.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.0/ui-bootstrap-tpls.min.js"></script>
    
    <div ng-app="myApp" ng-controller="MainController">
    
      <!--
       Modified day template to add an 'invis' class to secondary day buttons.
       This could/should be kept in a separate file (http://stackoverflow.com/a/26339919/446030)
       -->
      <script id="common/directives/uiBootstrapDatepickerDay.tpl.html" type="text/ng-template">
        <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>
              <th 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">
                <!--######## 'invis' class added in ng-class on the button: #######-->
                <button type="button" style="min-width:100%;" class="btn btn-default btn-sm" ng-class="{'btn-info': dt.selected, active: isActive(dt), 'invis': dt.secondary}" 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>
    
      <div>
        <strong>Selected date:</strong> {{dt.toDateString()}}
      </div>
      <div style="display:inline-block; min-height:290px;">
        <div datepicker ng-model="dt" class="well well-sm datepicker"></div>
      </div>
    
    </div>

    0 讨论(0)
提交回复
热议问题