【问题标题】:Angular UI Datepicker Limiting Days per monthAngular UI Datepicker 每月限制天数
【发布时间】:2015-10-13 09:24:43
【问题描述】:

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

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 天硬编码为更小的值,但它破坏了日历计算。只是看看有没有人以前扩展过这个?

干杯

【问题讨论】:

    标签: javascript angularjs datepicker angular-ui-bootstrap


    【解决方案1】:

    如果您使用装饰器,您应该能够将_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--;
        }
      }
    }
    

    作为一个正常运行的 sn-p,包括一个自定义模板和一些用于隐藏“次要”天(来自不同月份的天)的 css:

    (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>

    【讨论】:

    • 谢谢Jct,我试试看。但我怀疑只是删除行会影响周/月的计算方式,当随着时间的推移向前和向后移动时。让你知道我怎么走
    • 我在答案的底部添加了一个功能正常的 sn-p,其中包括覆盖以及自定义模板/css 以使次要日期不可见 - 这样它只显示日期当前月份。我不得不将自定义模板内联到脚本标记中,因为 sn-p 中不能有多个 .html 文件。不过,希望这有助于将所有部分放在一起。
    【解决方案2】:

    好吧,我代表ADMdtp 模块。它是纯 AngularJs dateTimePicker,带有禁用模式和其他许多很棒的选项:

    • 与 ngModel 完全同步,因此无需销毁或手动更新 dateTimePicker。
    • 高级范围选择器;将尽可能多的 dateTimePicker 关联在一起,并且无需销毁或手动更新每个 dateTimePicker。
    • 禁用模式;您可以轻松禁用一周或一个月中的任何一天,例如所有周末。
    • 在不断变化的日子过渡。 (诅咒你可以在选项中禁用它)
    • 获取完整的日期详细信息,例如 UNIX 格式的日期、日期格式和年、月、日、小时和分钟,以及...通过完整数据属性。
    • ...

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-09
      • 1970-01-01
      • 2015-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多