移动日历选中控件

阅读更多

二. 功能说明

  1. 支持切换年份,月份。

  2. 支持点击选中日期,也可以点击确定选择日期
三. 使用方法

  1. 添加Input

    在你的页面中添加Input输入框。可以再html里,也可以JS动态加载。

    我这里使用的时Input-group形式的输入框,是JS加载的。

    一般使用的话,直接写个input输入框就行。

'
' +
'申购成交时间' +
'' +
'
';

  2. 调用方法

    可选择项目:最大、最小日期。

$('.item-buydate').mdater();

  3. 源代码

    注意:注意更改代码中的图片资源路径。
  (function($) {
  $.fn.mdater = function(config) {
    var defaults = {
      maxDate: null,
      minDate: new Date(1970, 0, 1)
    };
    var option = $.extend(defaults, config);
    //window.console && console.log(this);
    var input = this;

    //通用函数
    var F = {
      //计算某年某月有多少天
      getDaysInMonth: function(year, month) {
        return new Date(year, month + 1, 0).getDate();
      },
      //计算某月1号是星期几
      getWeekInMonth: function(year, month) {
        return new Date(year, month, 1).getDay();
      },
      getMonth: function(m) {
        return ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '十一', '十二'][m];
      },
      //计算年某月的最后一天日期
      getLastDayInMonth: function(year, month) {
        return new Date(year, month, this.getDaysInMonth(year, month));
      }
    }
   //为$扩展一个方法,以配置的方式代理事件
    $.fn.delegates = function(configs) {
      el = $(this[0]);
      for (var name in configs) {
        var value = configs[name];
        if (typeof value == 'function') {
          var obj = {};
          obj.click = value;
          value = obj;
        };
        for (var type in value) {
          el.delegate(name, type, value[type]);
        }
      }
      return this;
    }

    var mdater = {
      value: {
        year: '',
        month: '',
        date: ''
      },
      lastCheckedDate: '',
      init: function() {
        this.initListeners();
      },
      renderHTML: function() {
        var $html = $('
    ');
            if ($('.md_mask').length == 0) { $(document.body).append($html); }
            return $html;
          },
          _showPanel: function(container) {
            this.refreshView();
            $('.md_panel, .md_mask').addClass('show');
          },
          _hidePanel: function() {
            //$('.md_panel, .md_mask').removeClass('show');
            $('.md_panel, .md_mask').remove();
          },
          _changeMonth: function(add, checkDate) {

            //先把已选择的日期保存下来
            this.saveCheckedDate();

            var monthTag = $('.md_selectarea').find('.monthtag'),
              num = ~~monthTag.data('month') + add;
            //月份变动发生了跨年
            if (num > 11) {
              num = 0;
              this.value.year++;
              $('.yeartag').text(this.value.year).data('year', this.value.year);
            } else if (num < 0) {
              num = 11;
              this.value.year--;
              $('.yeartag').text(this.value.year).data('year', this.value.year);
            }

            var nextMonth = F.getMonth(num) + '月';
            monthTag.text(nextMonth).data('month', num);
            this.value.month = num;
            if (checkDate) {
              this.value.date = checkDate;
            } else {
              //如果有上次选择的数据,则进行赋值
              this.setCheckedDate();
            }
            this.updateDate(add);
          },
          _changeYear: function(add) {
            //先把已选择的日期保存下来
            this.saveCheckedDate();

            var yearTag = $('.md_selectarea').find('.yeartag'),
              num = ~~yearTag.data('year') + add;
            yearTag.text(num + '年').data('year', num);
            this.value.year = num;

            this.setCheckedDate();

            this.updateDate(add);
          },
          //保存上一次选择的数据
          saveCheckedDate: function() {
            if (this.value.date) {
              this.lastCheckedDate = {
                year: this.value.year,
                month: this.value.month,
                date: this.value.date
              }
            }
          },
          //将上一次保存的数据恢复到界面
          setCheckedDate: function() {
            if (this.lastCheckedDate && this.lastCheckedDate.year == this.value.year && this.lastCheckedDate.month == this.value.month) {
              this.value.date = this.lastCheckedDate.date;
            } else {
              this.value.date = '';
            }
          },
          //根据日期得到渲染天数的显示的HTML字符串
          getDateStr: function(y, m, d) {
            var dayStr = '';
            //计算1号是星期几,并补上上个月的末尾几天
            var week = F.getWeekInMonth(y, m);
            var lastMonthDays = F.getDaysInMonth(y, m - 1);
            for (var j = week - 1; j >= 0; j--) {
              dayStr += '
  • ' + (lastMonthDays - j) + '
  • ';
            }
            //再补上本月的所有天;
            var currentMonthDays = F.getDaysInMonth(y, m);
            //判断是否超出允许的日期范围
            var startDay = 1,
              endDay = currentMonthDays,
              thisDate = new Date(y, m, d),
              firstDate = new Date(y, m, 1);
            lastDate = new Date(y, m, currentMonthDays),
              minDateDay = option.minDate.getDate();


            if (option.minDate > lastDate) {
              startDay = currentMonthDays + 1;
            } else if (option.minDate >= firstDate && option.minDate <= lastDate) {
              startDay = minDateDay;
            }

            if (option.maxDate) {
              var maxDateDay = option.maxDate.getDate();
              if (option.maxDate < firstDate) {
                endDay = startDay - 1;
              } else if (option.maxDate >= firstDate && option.maxDate <= lastDate) {
                endDay = maxDateDay;
              }
            }


            //将日期按允许的范围分三段拼接
            for (var i = 1; i < startDay; i++) {
              dayStr += '
  • ' + i + '
  • ';
            }
            for (var j = startDay; j <= endDay; j++) {
              var current = '';
              if (y == this.value.year && m == this.value.month && d == j) {
                current = 'current';
              }
              dayStr += '
  • ' + j + '
  • ';
            }
            for (var k = endDay + 1; k <= currentMonthDays; k++) {
              dayStr += '
  • ' + k + '
  • ';
            }

            //再补上下个月的开始几天
            var nextMonthStartWeek = (currentMonthDays + week) % 7;
            if (nextMonthStartWeek !== 0) {
              for (var i = 1; i <= 7 - nextMonthStartWeek; i++) {
                dayStr += '
  • ' + i + '
  • ';
              }
            }

            return dayStr;
          },
          updateDate: function(add) {
            var dateArea = $('.md_datearea.in');
            if (add == 1) {
              var c1 = 'out_left';
              var c2 = 'out_right';
            } else {
              var c1 = 'out_right';
              var c2 = 'out_left';
            }
            var newDateArea = $('
      ');
              newDateArea.html(this.getDateStr(this.value.year, this.value.month, this.value.date));
              $('.md_body').append(newDateArea);
              setTimeout(function() {
                newDateArea.removeClass(c2).addClass('in');
                dateArea.removeClass('in').addClass(c1);
              }, 0);

            },
            //每次调出panel前,对界面进行重置
            refreshView: function() {
              if (this.input.hasClass('input-group')) {
                var initVal = this.input.children('input').val();
              } else {
                var initVal = this.input.val();
              }
              var date = null;
              if (initVal) {
                var arr = initVal.split('-');
                date = new Date(arr[0], arr[1] - 1, arr[2]);
              } else {
                date = new Date();
              }
              var y = this.value.year = date.getFullYear(),
                m = this.value.month = date.getMonth(),
                d = this.value.date = date.getDate();
              $('.yeartag').text(y).data('year', y);
              $('.monthtag').text(F.getMonth(m) + '月').data('month', m);
              var dayStr = this.getDateStr(y, m, d);
              $('.md_datearea').html(dayStr);
            },
            input: null, //暂存当前指向input
            initListeners: function() {
              var _this = this;
              input.on('click', function() {
                _this.input = $(this); //暂存当前指向input
                if ($('.md_mask').length) {
                  _this._hidePanel();
                } else {
                  _this.renderHTML();
                  var panel = $('.md_panel'),
                    mask = $('.md_mask');
                  _this.afterShowPanel(mask, panel);
                  setTimeout(function() {
                    _this._showPanel();
                  }, 50);
                }
              });
            },
            saveValueToInput: function() {
              var _this = this;
              var monthValue = ~~_this.value.month + 1;
              if (monthValue < 10) {
                monthValue = '0' + monthValue;
              }
              var dateValue = _this.value.date;
              if (dateValue === '') {
                dateValue = _this.value.date = 1;
              }
              if (dateValue < 10) {
                dateValue = '0' + dateValue;
              }
              if (_this.input.hasClass('input-group')) {
                _this.input.children('input').val(_this.value.year + '-' + monthValue + '-' + dateValue);
                _this.input.children('input').trigger('input');
              } else {
                _this.input.val(_this.value.year + '-' + monthValue + '-' + dateValue);
                _this.input.trigger('input');
              }
              _this._hidePanel();
            },
            afterShowPanel: function(mask, panel) {
              var _this = this;
              mask.on('click', function() {
                _this._hidePanel();
              });
              panel.delegates({
                '.change_month': function() {
                  var add = $(this).hasClass('md_next') ? 1 : -1;
                  _this._changeMonth(add);
                },
                '.change_year': function() {
                  var add = $(this).hasClass('md_next') ? 1 : -1;
                  _this._changeYear(add);
                },
                '.out_left, .out_right': {
                  'webkitTransitionEnd': function() {
                    $(this).remove();
                  }
                },
                '.md_datearea li': function() {
                  var $this = $(this);
                  if ($this.hasClass('disabled')) {
                    return;
                  }
                  _this.value.date = $this.data('day');
                  //判断是否点击的是前一月或后一月的日期
                  var add = 0;
                  if ($this.hasClass('nextdate')) {
                    add = 1;
                  } else if ($this.hasClass('prevdate')) {
                    add = -1;
                  }
                  if (add !== 0) {
                    _this._changeMonth(add, _this.value.date);
                  } else {
                    $this.addClass('current').siblings('.current').removeClass('current');
                    _this.saveValueToInput();
                  }
                },
                '.md_cancel': function() {
                  _this._hidePanel();
                },
                '.md_ok': function() {
                  _this.saveValueToInput();
                }
              });
            }
          }
          mdater.init();
        }
      })(window.Zepto || window.jQuery);

      复制代码


      复制代码

      a {
        -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
        -webkit-tap-highlight-color: transparent;
      }

      .md_mask {
        width: 100%;
        height: 100%;
        -moz-transition: opacity .5s linear 0s;
        -webkit-transition: opacity .5s linear 0s;
        -o-transition: opacity .5s linear 0s;
        -ms-transition: opacity .5s linear 0s;
        transition: opacity .5s linear 0s;
        position: absolute;
        top: 0;
        left: 0;
        display: block;
        visibility: hidden;
        background: #000;
        opacity: 0;
        z-index: 1000;
      }

      .md_mask.show {
        visibility: visible;
        opacity: 0.25;
      }

      .md_panel {
        -moz-transition: -moz-transform .3s ease-in-out 0s;
        -ms-transition: -ms-transform .3s ease-in-out 0s;
        -webkit-transition: -webkit-transform .3s ease-in-out 0s;
        -o-transition: -o-transform .3s ease-in-out 0s;
        transition: transform .3s ease-in-out 0s;
        -ms-transform: translate3d(0, 100%, 0);
        -moz-transform: translate3d(0, 100%, 0);
        -webkit-transform: translate3d(0, 100%, 0);
        -o-transform: translate3d(0, 100%, 0);
        transform: translate3d(0, 100%, 0);
        position: fixed;
        bottom: 0;
        left: 0;
        width: 100%;
        height: auto;
        z-index: 1100;
        background-color: #F7F7F7;
        font-family: Tahoma, arial, verdana, sans-serif;
        -webkit-user-select: none;
      }

      .md_panel.show {
        -ms-transform: translate3d(0, 0, 0);
        -moz-transform: translate3d(0, 0, 0);
        -webkit-transform: translate3d(0, 0, 0);
        -o-transform: translate3d(0, 0, 0);
        transform: translate3d(0, 0, 0);
      }

      .md_panel a {
        text-decoration: none;
      }

      .md_selectarea {
        display: inline-block;
        width: 50%;
        position: relative;
      }

      .md_head {
        height: 40px;
        line-height: 40px;
      }

      .md_body {
        position: relative;
        height: 268px;
      }

      .md_headtext {
        display: inline-block;
        width: 100%;
        text-align: center;
        font-size: 1.125em;
        color: #333;
      }

      .md_prev,
      .md_next {
        position: absolute;
        top: 0;
        font-family: arial;
        font-size: 1.6em;
        display: inline-block;
        width: 40px;
        height: 40px;
        text-align: center;
      }

      .md_prev {
        left: 0;
      }

      .md_next {
        right: 0;
      }

      .md_weekarea {
        margin: 0;
        padding: 0;
        list-style-type: none;
        overflow: hidden;
      }

      .md_weekarea li,
      .md_datearea li {
        display: inline-block;
        float: left;
        width: 14.2857%;
        font-size: .8125em;
        font-weight: 400;
        text-align: center;
        line-height: 3.31em;
      }

      .md_weekarea li,
      .md_prev,
      .md_next {
        color: #5b5b5b;
      }

      .md_datearea {
        position: absolute;
        width: 100%;
        list-style-type: none;
        margin: 0;
        padding: 0;
        overflow: hidden;
        -webkit-transition: -webkit-transform .2s ease-in;
        -webkit-transform: translate3d(0, 0, 0);
      }

      .md_datearea li.current {
        background-color: #872F9F;
        color: #FFF;
        border-radius: 4px;
      }

      .md_datearea li span {
        display: inline-block;
        width: 100%;
        height: 100%;
      }

      .md_datearea li span.current {
        background-color: #872F9F;
        color: #FFF;
      }

      .md_foot {
        margin-top: 0.5em;
        margin-bottom: 1em;
        text-align: center;
      }

      .md_ok,
      .md_cancel {
        display: -moz-inline-stack;
        display: inline-block;
        *display: inline;
        *zoom: 1;
        width: 9em;
        height: 2.5em;
        line-height: 2.5em;
        border-radius: 4px;
      }

      .md_ok {
        color: #fff;
        background-color: #872F9F;
      }

      .md_cancel {
        color: #fff;
        margin-left: 1em;
        background-color: #C6C6C6;
      }

      .out_left {
        -webkit-transform: translate3d(-100%, 0, 0);
      }

      .out_right {
        -webkit-transform: translate3d(100%, 0, 0);
      }

      .prevdate,
      .nextdate {
        color: #999;
      }

      .disabled {
        color: #C6C6C6;
      }







      你可能感兴趣的:(移动日历选中控件)