Angular UI Datepicker每月限制天数

时间:2015-07-23 07:46:23

标签: javascript angularjs datepicker angular-ui-bootstrap

我正在使用角度日期选择器:

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

目前,它被硬编码显示42天或6周。

我想知道如何在ui-bootstrap-0.13.1.js中覆盖(即角度装饰器)这个函数,以显示4周。

这是功能:

ctrl._refreshView = function() {
  var year = ctrl.activeDate.getFullYear(),
    month = ctrl.activeDate.getMonth(),
    firstDayOfMonth = new Date(year, month, 1),
    difference = ctrl.startingDay - firstDayOfMonth.getDay(),
    numDisplayedFromPreviousMonth = (difference > 0) ? 7 - difference : -difference,
    firstDate = new Date(firstDayOfMonth);

  if (numDisplayedFromPreviousMonth > 0) {
    firstDate.setDate(-numDisplayedFromPreviousMonth + 1);
  }

  // 42 is the number of days on a six-month calendar
  var days = getDates(firstDate, 42);
  for (var i = 0; i < 42; i++) {
    days[i] = angular.extend(ctrl.createDateObject(days[i], ctrl.formatDay), {
      secondary: days[i].getMonth() !== month,
      uid: scope.uniqueId + '-' + i
    });
  }

  scope.labels = new Array(7);
  for (var j = 0; j < 7; j++) {
    scope.labels[j] = {
      abbr: dateFilter(days[j].date, ctrl.formatDayHeader),
      full: dateFilter(days[j].date, 'EEEE')
    };
  }

  scope.title = dateFilter(ctrl.activeDate, ctrl.formatDayTitle);
  scope.rows = ctrl.split(days, 7);

  if (scope.showWeeks) {
    scope.weekNumbers = [];
    var thursdayIndex = (4 + 7 - ctrl.startingDay) % 7,
      numWeeks = scope.rows.length;
    for (var curWeek = 0; curWeek < numWeeks; curWeek++) {
      scope.weekNumbers.push(
        getISO8601WeekNumber(scope.rows[curWeek][thursdayIndex].date));
    }
  }
};

我已经尝试将42天硬编码到更小的东西,但它打破了日历计算。只是看看是否有人已经扩展过这个?

干杯

2 个答案:

答案 0 :(得分:3)

如果使用装饰器,您应该能够在包含旧链接函数的新编译函数中包装_refreshView。在ctrl._refreshView包装器中,您可以执行以下操作:

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);
  };
};

//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--;
    }
  }
}

所有这些都是一个功能正常的代码段,包括一个自定义模板和一些用于隐藏&#39;二级&#39;天(来自不同月份的那些):

&#13;
&#13;
(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();
  }
})();
&#13;
/*
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;
}
&#13;
<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>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

好吧,我代表ADMdtp模块。它是纯粹的AngularJs dateTimePicker,具有禁用模式和其他大量的greate选项:

  • 与ngModel完全同步,因此无需销毁或手动更新dateTimePicker。
  • 高程范围选择器;根据需要制作尽可能多的dateTimePicker,再次无需销毁或手动更新每个dateTimePicker。
  • 禁用模式;很容易就可以在周或月中禁用任何一天,就像所有周末一样。
  • 在变化的日子过渡。 (诅咒你可以在选项中禁用它)
  • 获取完整日期详细信息,例如UNIX格式的日期,日期格式和年,月,日,小时和分钟,以及...全数据属性。
  • ...

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