Kalendae 三个日历 时间连选

本文介绍了如何使用Kalendae日历控件实现一个三联日历,允许用户选择一个时间段。通过修改控件的语言、日期格式、初始化时间以及回显设置,使其适应中文环境并满足特定需求。在实现过程中,还解决了在不同IE版本中的兼容性问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 工作中要求一个三联日历,时间可连选一个时间段,如下图

经过一段时间的搜索和查找最终选定用Kalendae日期控件,原因是有一个可参考的demo,可网上针对这个时间控件的描述千篇一律的将demo中的方法简单的进行了描述,可学习和借鉴的东西少之又少,无奈,改吧(本人做java的 看js代码还是有点费劲)。

一步一步来,这里使用的方法是原js代码生改(生改:就是硬改,硬改:就是直接改)。

第一步先将英文改为中文

修改Language.prototype 这个大家看到都会改,就是把英文日期相关的词语改成中文的

  //_months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
        _months : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),
        months : function (m) {
            return this._months[m.month()];
        },

        _monthsShort : "一_二_三_四_五_六_七_八_九_十_十一_十二".split("_"),

        _weekdays : "星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),
        weekdays : function (m) {
            return this._weekdays[m.day()];
        },

        _weekdaysShort : "周日_周一_周二_周三_周四_周五_周六".split("_"),
        weekdaysShort : function (m) {
            return this._weekdaysShort[m.day()];
        },

        _weekdaysMin : "日_一_二_三_四_五_六".split("_"),
        weekdaysMin : function (m) {
            return this._weekdaysMin[m.day()];
        },

第二步修改日历的日期显示格式

columnHeaderFormat    :'dd',            /* number of characters to show in the column headers */
  titleFormat           :'YYYY年MMMM ',    /* format mask for month titles. See momentjs.com for rules  edt  by quzh*/
  dayNumberFormat       :'D',             /* format mask for individual days */
  dayAttributeFormat    :'YYYY-MM-DD',    /* format mask for the data-date attribute set on every span */
  parseSplitDelimiter   : /,\s*|\s+-\s+/, /* regex to use for splitting multiple dates from a passed string */

第三步设置日历初始化显示的时间(默认以当前月为最左边的日期,因为我要选的时间为本天以前的时间所以我修改为显示我选择时间第一所在月向前两个月为最左边的日历时间)

 setSelected : function (input, draw) {
  var i,
   new_dates = parseDates(input, this.settings.parseSplitDelimiter, this.settings.format),
   old_dates = parseDates(this.getSelected(), this.settings.parseSplitDelimiter, this.settings.format);

  i = old_dates.length;
  while(i--) { this.removeSelected(old_dates[i], false); }

  i = new_dates.length;
  while(i--) { this.addSelected(new_dates[i], false); }

  if (draw !== false) {
   if (new_dates[0]) {
    var d=new Date();
    //edt by quzh
    //方法一 从选中日期开始日期的前两个月开始显示 
    this.viewStartDate = moment(new_dates[0], this.settings.format).add({M:-2});//从 当前月前两个月开始显示
    //方法二 从当前日期的前两个月开始显示
    /*var newdate =new Date();//将开始时间由时间戳转换为 时间格式2014-05-01
    var year = newdate.getFullYear();
    var month = newdate.getMonth()+1;
    var day = newdate.getDay()
    var CurrentDate = "";
    CurrentDate += year+"/";
       if (month >= 10 ){
        CurrentDate += month+"/";
       }
       else{
        CurrentDate += "0" + month+"/";
       }
       if (day >= 10 ){
        CurrentDate += day ;
       }
       else{
        CurrentDate += "0" + day ;
       }
    this.viewStartDate = moment(moment(CurrentDate, this.settings.format).hours(12), this.settings.format).add({M:-2});*/
   }
   this.draw();
  }
 },

第四步 设置日期的在文本框中的显示格式

defaults : util.merge(Kalendae.prototype.defaults, {
  format: 'YYYY/MM/DD',//设置显示的时间格式 edt by quzh
  side: 'bottom',
  closeButton: true,
  offsetLeft: 0,
  offsetTop: 0
 }),

第五步设置日期时间回显(选择了一段时间,当再次点开是该段时间还为选中状态)

<input class="auto-kal" id="queryTime"
      name="hdRealtimeTotale.dateTime" size="22"
      data-kal="months: 3,mode:'range' ,direction: 'today-past',viewStartDate:Kalendae.moment().subtract({M:3}),selected:[Kalendae.moment().subtract({d:<%=-hdRealtimeTotale.getStart2Now()%>}), Kalendae.moment().add({d:<%=hdRealtimeTotale.getEnd2Now()%>})]"
      οnchange="setDateTime();"
      value="<%=hdRealtimeTotale.getDateTime()%>" />

 

在这里比较重要的有

class class="auto-kal" 如果想显示出如文章开始的日历控件 class 就写这个

data-kal 这个属性是设置日历参数的,参数解释如下

months: 3 显示三个月的日历

mode:'range'  日历模型为连选

direction: 'today-past' 选择的日期为今天以前(包括今天)

viewStartDate:Kalendae.moment().subtract({M:3}) 选择选中日期开始前2个月的日期作为最(左边的日历)

selected:[Kalendae.moment().subtract({d:i}), Kalendae.moment().add({d:j})]

这里i为选中开始那天距离当前日期的天数

这里的j为选中结束那天距离当前的天数(如果是之前的日期的话 这个值应该为负数)

 

至此日历日历基本可以使用了

但是。。。。。。。。。

在尝试修改的时候 我用的浏览器版本为IE11 后来发现 除了IE11都不好使哭

 

继续修改。。。。

首先找到问题是 js中没有获取到页面对象,于是我认定为页面没有加载完全就初始化获取对象了,我将js在页面获取完全了再去获取对象,还是不正确 但是问题和刚刚的报错不一致,经过反复测试,将js中的获取表单对象增加监听事件的代码提到页面待表单加载完全再执行其余代码还需先行加载

$(document).ready(function (){
  //此方法必须在页面加载完全后执行 所以从kalendae.standalone.js 文件中摘出
  //auto-initializaiton code
  if (typeof document.addEventListener === 'function'||typeof window.attachEvent !="undefined") Kalendae.util.domReady(function () {
   var els = Kalendae.util.$$('.auto-kal'),
    i = els.length,
    e,
    options,
    optionsRaw;

   while (i--) {
    e = els[i];
    optionsRaw = e.getAttribute('data-kal');
    options = (optionsRaw == null || optionsRaw == "") ? {} : (new Function('return {' + optionsRaw + '};'))();
    if (e.tagName === 'INPUT') {
     //if element is an input, bind a popup calendar to the input.
     new Kalendae.Input(e, options);
    } else {
     //otherwise, insert a flat calendar into the element.
     new Kalendae(util.merge(options, {attachTo:e}));
    }

   }
  });
  setTotalType( $("#totalType").attr("value"));
 });

就这段, 记得将js中的注释掉,至此已经解决了ie10 ie9的兼容问题

 

但是。。。还有个东西叫IE8.。。。。。。

 

具体原因很纠结 改的内容如下

this._events.inputFocus = util.addEvent($input, 'focus', function () {
  changing = true; // prevent setSelected from altering the input contents.
  if(!isIE8){
   self.setSelected(this.value);
  }
  isIE8 = false;
  changing = false;
  self.show();
 });

 this._events.inputBlur = util.addEvent($input, 'blur', function () {
  if (noclose && util.isIE8()) {
   noclose = false;
   isIE8 = true;
   $input.focus();
  }
  else self.hide();
 });

 

好了 就这些问题 有高手可以通过外部设置解决这些问题 希望跟帖

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值