datepicker 增加选择年月及自定义到某个月份

首先声明一下,这个插件的原创作者是  MoBinni

GITHUB地址请访问:https://github.com/mobinni/material-date-picker

(function() {
  'use strict';

  /**
    * By Mo Binni
   */
  var app, contains;

  app = angular.module('materialDatePicker', []);

  contains = function(container, contained) {
    var node;
    node = contained.parentNode;
    while (node !== null && node !== container) {
      node = node.parentNode;
    }
    return node !== null;
  };

  app.directive("outsideClick", [
    '$document', '$parse', function($document, $parse) {
      return {
        link: function($scope, $element, $attributes) {
          var onDocumentClick, scopeExpression;
          scopeExpression = $attributes.outsideClick;
          onDocumentClick = function(event) {
            if (!contains($element[0], event.target)) {
              $scope.$apply(scopeExpression);
            }
          };
          $document.on("click", onDocumentClick);
          $element.on("$destroy", function() {
            $document.off("click", onDocumentClick);
          });
        }
      };
    }
  ]);

  app.directive('mbDatepicker', [
    '$filter', function($filter) {
      return {
        scope: {
          elementId: '@',
          date: '=',
          dateFormat: '@',
          minDate: '@',
          maxDate: '@',
          inputClass: '@',
          inputName: '@',
          placeholder: '@',
          arrows: '=?',
          calendarHeader: '=?',
          utcMode: '=',
          ngDisabled: '=',
          label: '@',
          customInputClass: '@',
          rightclass: '=',
          //  previousMonth:'@'
        },
          template: '<div id="dateSelectors" class="date-selectors"  outside-click="hidePicker()" style="display:inline-block;"> <label ng-bind="label" class="mb-input-label" for="{{inputName}}"></label> <input name="{{ inputName }}" type="text" ng-disabled="{{ngDisabled}}" ng-class="{disabled: ngDisabled}" class="mb-input-field {{customInputClass}}"  ng-click="showPicker()"  class="form-control" id="{{inputName}}" ng-model="date" placeholder="{{ placeholder }}" style="font-size: 14px"> <div class="mb-datepicker" ng-show="isVisible"> <table> <caption> <div class="header-year-wrapper"> <span style="display: inline-block; float: left; padding-left:20px; cursor: pointer" class="noselect" ng-click="previousYear(currentDate)"><img style="height: 10px;" ng-src="{{ arrows.year.left }}"/></span> <span class="header-year noselect" ng-class="noselect">{{ year }}</span> <span style="display: inline-block; float: right; padding-right:20px; cursor: pointer" class="noselect" ng-click="nextYear(currentDate)"><img style="height: 10px;" ng-src="{{ arrows.year.right }}"/></span> </div> <div ng-hide="onlyMonth" class="header-nav-wrapper"> <span class="header-item noselect" style="float: left; cursor:pointer" ng-click="previousMonth(currentDate)"><img style="height: 10px;" ng-src="{{ arrows.month.left }}"/></span> <span class="header-month noselect">{{ month }}</span> <span class="header-item header-right noselect" style="float: right; cursor:pointer" ng-click="nextMonth(currentDate)"> <img style="height: 10px;" ng-src="{{ arrows.month.right }}"/></span> </div> </caption> <tbody><tr ng-show="onlyMonth" class="days" ng-repeat="week in months"> <td ng-click="selectMonth(day)" class="noselect" ng-class="::day.class" ng-repeat="day in week" style="width: 50px;text-align: center"><div style="display: block;" ng-class="{selected: selectedDate === day.selected}"> {{ ::day}} </div> </td></tr><tr ng-hide="onlyMonth"><td class="day-head">{{ ::calendarHeader.monday }}</td> <td class="day-head">{{ ::calendarHeader.tuesday }}</td><td class="day-head">{{ ::calendarHeader.wednesday }}</td> <td class="day-head">{{ ::calendarHeader.thursday }}</td> <td class="day-head">{{ ::calendarHeader.friday }}</td> <td class="day-head">{{ ::calendarHeader.saturday }}</td><td class="day-head">{{ ::calendarHeader.sunday }}</td> </tr> <tr ng-hide="onlyMonth" class="days" ng-repeat="week in weeks"> <td ng-click="selectDate(day)" class="noselect" ng-class="::day.class" ng-repeat="day in week"><div style="display: block;" ng-class="{selected: selectedDate === day.selected}"> {{ ::day.value }} </div> </td> </tr></tbody></table> </div> </div>',
          restrict: 'E',
          transclude: true,
          link: function(scope, element, attrs) {
              if(attrs.startDate){
                  var formatStartTime;
                  if (attrs.runTo) {
                      formatStartTime = util.getFormatDate().year + '-' + util.getFormatDate().moth + '-' + util.getFormatDate().day;
                  } else {
                      formatStartTime = util.getFormatDate().year + '-' + util.getFormatDate().moth + '-' + '01';
                  }
                  scope.date = formatStartTime
              }
              if(attrs.endDate){
                  var formatendTime = util.getFormatDate().year + '-' + util.getFormatDate().moth + '-' + util.getFormatDate().day
                  scope.date = formatendTime
              }
              var getWeeks, init, selectors, today;
              selectors = document.querySelector('#dateSelectors');
              today = moment();
              if (scope.utcMode) {
                  today.utc();
              }
              scope.month = '';
              scope.year = today.year();
              if (scope.inputClass) {
                  selectors.className = selectors.className + " " + scope.inputClass;
              }
              if (!scope.dateFormat) {
                  scope.dateFormat = "YYYY-MM-DD";
              }
              if (scope.minDate) {
                  scope.minDate = moment(scope.minDate, scope.dateFormat);
                  if (scope.utcMode) {
                      scope.minDate.utc();
                  }
              }
              if (scope.maxDate) {
                  scope.maxDate = moment(scope.maxDate, scope.dateFormat);
                  if (scope.utcMode) {
                      scope.maxDate.utc();
                  }
              }
              if (!scope.calendarHeader) {
                  scope.calendarHeader = {
                      monday: $filter('date')(new Date(moment().isoWeekday(1)), 'EEE'),
                      tuesday: $filter('date')(new Date(moment().isoWeekday(2)), 'EEE'),
                      wednesday: $filter('date')(new Date(moment().isoWeekday(3)), 'EEE'),
                      thursday: $filter('date')(new Date(moment().isoWeekday(4)), 'EEE'),
                      friday: $filter('date')(new Date(moment().isoWeekday(5)), 'EEE'),
                      saturday: $filter('date')(new Date(moment().isoWeekday(6)), 'EEE'),
                      sunday: $filter('date')(new Date(moment().isoWeekday(7)), 'EEE')
                  };
              }
              if (!scope.arrows) {
                  scope.arrows = {
                      year: {
                          left: '../images/svg/white_arrow_left.svg',
                          right: '../images/svg/white_arrow_right.svg'
                      },
                      month: {
                          left: '../images/svg/grey_arrow_left.svg',
                          right: '../images/svg/grey_arrow_right.svg'
                      }
                  };
              }
              function formateMonth(obj){
                  if(obj){
                      return  obj.slice(0,-1);
                  }
              }
              //月份选择
              if(attrs.onlyMonth){
                  scope.onlyMonth=true;
                  scope.arrows = {
                      year: {
                          left: '../images/svg/grey_arrow_left.svg',
                          right: '../images/svg/grey_arrow_right.svg'
                      },
                  };
                  scope.months=[{"day":"1月","day1":"2月","day2":"3月"},{"day":"4月","day1":"5月","day2":"6月"},{"day":"7月","day1":"8月","day2":"9月"},{"day":"10月","day1":"11月","day2":"12月"}];

                  scope.selectMonth = function(day) {
                      if(day){
                          day=formateMonth(day)
                          if(day<10) day='0'+day;
                          scope.date = scope.year+'-'+day;
                          return scope.isVisible = false;
                      }
                      return
                  };
              }else{
                  scope.onlyMonth=false;
              }
              getWeeks = function(monthLength, startDay, month) {
                  var chunk_size, day, j, monthDays, newDate, ref, start, weeks;
                  monthDays = [];
                  for (day = j = 0, ref = monthLength; 0 <= ref ? j <= ref : j >= ref; day = 0 <= ref ? ++j : --j) {
                      start = moment(startDay);
                      if (scope.utcMode) {
                          start.utc();
                      }
                      newDate = start.add(day, 'd');
                      day = {
                          date: newDate,
                          value: newDate.format('DD')
                      };
                      if (scope.minDate && moment(newDate, scope.dateFormat) <= moment(scope.minDate, scope.dateFormat)) {
                          day.isToday = true;
                          day.isEnabled = false;
                          day["class"] = 'disabled';
                          monthDays.push(day);
                      } else if (scope.maxDate && moment(newDate, scope.dateFormat) >= moment(scope.maxDate, scope.dateFormat)) {
                          day.isToday = true;
                          day.isEnabled = false;
                          day["class"] = 'disabled';
                      } else if (newDate.format(scope.dateFormat) === moment().format(scope.dateFormat)) {
                          day.isToday = true;
                          day.isEnabled = true;
                          day["class"] = 'day-item today';
                      } else if (newDate.month() === month) {
                          day.isToday = false;
                          day.isEnabled = true;
                          day["class"] = 'day-item day';
                      } else if (newDate.day() === 0 || newDate.day() === 6) {
                          day.isToday = false;
                          day.isEnabled = true;
                          day["class"] = 'day-item weekend';
                      } else {
                          day.isToday = false;
                          day.isEnabled = true;
                          day["class"] = 'day-item';
                      }
                      monthDays.push(day);
                  }
                  chunk_size = 7;
                  weeks = monthDays.map(function(e, i) {
                      if (i % chunk_size === 0) {
                          return monthDays.slice(i, i + chunk_size);
                      } else {
                          return null;
                      }
                  }).filter(function(e) {
                      return e;
                  });
                  if (weeks) {
                      return weeks;
                  } else {
                      return [];
                  }
              };
              scope.nextMonth = function(date) {
                  var first_day, last_day, next_month;
                  next_month = moment(date).date(0);
                  last_day = moment(next_month).add(4, 'months').date(0);
                  scope.year = last_day.year();
                  if (last_day.day() !== 7) {
                      last_day = last_day.add(7 - last_day.day(), 'days');
                  }
                  first_day = moment(next_month).add(2, 'months').startOf('isoweek');
                  scope.currentDate = first_day;
                  scope.weeks = [];
                  scope.weeks = getWeeks(last_day.diff(first_day, 'days'), first_day, next_month.add(3, 'months').month());
                  return scope.month = $filter('date')(new Date(next_month), 'MMM');
              };
              scope.previousMonth = function(date) {
                  var first_day, last_day, last_month;
                  last_month = moment(date).date(0);
                  last_day = moment(last_month).add(2, 'months').date(0);
                  scope.year = last_day.year();
                  if (last_day.day() !== 7) {
                      last_day = last_day.add(7 - last_day.day(), 'days');
                  }
                  first_day = moment(last_month).startOf('isoweek');
                  scope.currentDate = first_day;
                  scope.weeks = [];
                  scope.weeks = getWeeks(last_day.diff(first_day, 'days'), first_day, last_month.add(1, 'months').month());
                  return scope.month = $filter('date')(new Date(last_month), 'MMM');
              };
              scope.nextYear = function(date) {
                  var first_day, last_day, next_month;
                  next_month = moment(date).date(0);
                  last_day = moment(next_month).add(1, 'year').add(3, 'months').date(0);
                  scope.year = last_day.year();
                  if (last_day.day() !== 7) {
                      last_day = last_day.add(7 - last_day.day(), 'days');
                  }
                  first_day = moment(next_month).add(1, 'years').add(1, 'months').startOf('isoweek');
                  scope.currentDate = first_day;
                  scope.weeks = [];
                  scope.weeks = getWeeks(last_day.diff(first_day, 'days'), first_day, next_month.add(2, 'months').month());
                  return scope.month = $filter('date')(new Date(next_month), 'MMM');
              };
              scope.previousYear = function(date) {
                  var first_day, last_day, last_month;
                  last_month = moment(date).date(0);
                  last_day = moment(last_month).subtract(1, 'years').add(3, 'months').date(0);
                  scope.year = last_day.year();
                  if (last_day.day() !== 7) {
                      last_day = last_day.add(7 - last_day.day(), 'days');
                  }
                  first_day = moment(last_month).subtract(1, 'years').add(1, 'months').startOf('isoweek');
                  scope.currentDate = first_day;
                  scope.weeks = [];
                  scope.weeks = getWeeks(last_day.diff(first_day, 'days'), first_day, last_month.add(2, 'months').month());
                  return scope.month = $filter('date')(new Date(last_month), 'MMM');
              };
              scope.selectDate = function(day) {
                  if (day.isEnabled) {
                      scope.date = day.date.format(scope.dateFormat);
                      // if (day.selected === scope.date) {
                      scope.selectedDate = day.selected;
                      // }
                  }
                  return scope.isVisible = false;
              };
              //获取标签内的默认时间
              if(attrs.nowDate){
                  scope.runMonth=  attrs.value+'-01'
              }
              scope.isVisible = false;
              scope.showPicker = function() {
                  //初始化的时候加载到默认时间
                  if(scope.runMonth){
                      scope.previousMonth(attrs.value);
                  }
                  scope.date = "";
                  scope.isVisible = true;
                  if(scope.rightclass){
                      $('#dateSelectors .mb-datepicker').css('right','0px');
                  }else{
                      $('#dateSelectors .mb-datepicker').removeAttr('style');
                  }
              };
              scope.hidePicker = function() {
                  scope.isVisible = false;
              };
              init = function() {
                  var days, endDate, firstMonday;
                  if (scope.utcMode) {
                      firstMonday = moment.utc(moment.utc().date(1)).startOf('isoweek');
                  } else {
                      firstMonday = moment(moment().date(1)).startOf('isoweek');
                  }
                  if (firstMonday.date() === 1) {
                      firstMonday.subtract(1, 'weeks');
                  }
                  days = moment(moment().date(today.month())).daysInMonth();
                  endDate = moment().add(1, 'months').date(0);
                  scope.month = $filter('date')(new Date(endDate), 'MMM');
                  if (endDate.day() !== 7) {
                      endDate = endDate.add(7 - endDate.day(), 'days');
                  }
                  scope.currentDate = firstMonday;
                  return scope.weeks = getWeeks(endDate.diff(firstMonday, 'days'), firstMonday, today.month());
              };
              return init();
          }
      };
      }
  ]);

}).call(this);
说明:使用方法:
<mb-datepicker id="startTime" input-class="form-control input-medium input-item" calendar-header="header" only-month="true"></mb-datepicker>
 这个自定义指令,主要是依赖于 attrs的属性和link方法进行关联。  
only-month 这个属性存在时,执行的是日期选择的逻辑。当需求是显示年月的时候,可以组件标签上增加这个属性,如果需求是展示年月日的时候,这个属性直接不写就可以。
<mb-datepicker id="time_accounting"
               input-class="form-control input-medium input-item input-item-width180 no-padding"
               calendar-header="header" date-format="YYYY-MM-DD"
               now-date="true" value={{nowvalue}}></mb-datepicker>
now-date 属性为true的时候,此功能是要触发日历的时候,自动定位到某个月份,具体的月份值存在 value的属性上,可以通过attrs.value来进行获取。
如果还需要进行选择范围的设定:比如选择日期只能选择某个月份,超出会提示。只需要定位到某个月份的时候,当文本框失去焦点的时候,对选择的内容进行截取,对比年月,如果不是统一月份就提示。
(、、、、编辑器粘代码比较乱,只提供个思路。谅解。。。有错误请指正。)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值