JS实现日期控件的可选日期范围

楼主
我是社区第485122位番薯,欢迎点我头像关注我哦~
1. 概述
1.1 问题描述

默认的日期控件的可选日期范围是一个连续的区间,而我们实际运用时可能需要的是离散的时间点,如下图只可选择本月的周四:


1.2 实现思路

通过 JavaScript 重写 FR 的日期控件,循环日期选项,判断日期是否是周四限制日期是否可选。

2. 示例
2.1 操作步骤

打开参数面板,拖入日期控件,给日期控件添加初始化后事件:


  1. this._createCalendar = function(){
  2. var o = this.options;
  3. var self = this;
  4. if (this.options.need2BuildConfig === true && this.options.data) {
  5. this.options.data.resetStatus(this.createDependencePara4Data());
  6. var data = this.options.data.getData();
  7. if (data[0].data) {
  8. if (data[0].data.startDate) {
  9. var sd = new Date(data[0].data.startDate);
  10. if (!FR.isInvalidDate(sd)) {
  11. o.startDate = FR.date2Str(sd, 'yyyy-MM-dd');
  12. this.std = this._createStartDate(o.startDate, o.format, this.viewMode);
  13. }
  14. }
  15. if (data[0].data.endDate) {
  16. var ed = new Date(data[0].data.endDate);
  17. if (!FR.isInvalidDate(ed)) {
  18. o.endDate = FR.date2Str(ed, 'yyyy-MM-dd');
  19. this.edd = this._createEndDate(o.endDate, o.format, this.viewMode);
  20. }
  21. }
  22. }
  23. this.options.rebuildConfig = false;
  24. }
  25. this.datepicker = new FR.DatePicker({
  26. renderEl: this.$view,
  27. viewMode: this.viewMode,
  28. date: FR.str2Date(this.editComp.val(), o.format),
  29. dateFormat: o.format,
  30. startDate: this.std,
  31. endDate: this.edd,
  32. onDateUpdate:function(){
  33. if ($(':focus').length === 0) {
  34. self.editComp.focus();
  35. }
  36. self.editComp.val(FR.date2Str(this.getValue(), o.format));
  37. self.isValidateInput();
  38. self.fireEvent(FR.Events.AFTEREDIT);
  39. }
  40. });
  41. this.datepicker._loadDateData = function (table, date) {
  42.         if (!date) {
  43.             return;
  44.         }
  45.         var year = date.getFullYear(),
  46.             month = date.getMonth(),
  47.             day = date.getDate();
  48.         var today = new Date(),
  49.             TY = today.getFullYear(),
  50.             TM = today.getMonth(),
  51.             TD = today.getDate();
  52.         this.cache.showYear = year;
  53.         this.cache.showMonth = month;
  54.         var std = this.options.startDate,
  55.             edd = this.options.endDate;
  56.         table.$title.text(Date._MN[month] + ", " + year);
  57.         var nextDay = new Date(date);
  58.         nextDay.setDate(nextDay.getMonthDays() + 1);
  59.         if ((edd && nextDay > edd) || nextDay.getFullYear() > this.CONSTS.MAXYEAR) {
  60.             table.$nextm.addClass('disabled').removeClass('hover').data('disabled', true);
  61.         } else {
  62.             table.$nextm.removeClass('disabled').data('disabled', false);
  63.         }
  64.         var prevDay = new Date(date);
  65.         prevDay.setDate(0);
  66.         if ((std && prevDay < std) || prevDay.getFullYear() < this.CONSTS.MINYEAR) {
  67.             table.$prevm.addClass('disabled').removeClass('hover').data('disabled', true);
  68.         } else {
  69.             table.$prevm.removeClass('disabled').data('disabled', false);
  70.         }
  71.         date.setDate(1);
  72.         var day1 = (date.getDay() - this.CONSTS.FIRSTDAY) % 7;
  73.         date.setDate(0 - day1);
  74.         date.setDate(date.getDate() + 1);
  75.         var $frow = table.find('tbody').children().eq(0);
  76.         for (var i = 0; i < 6; i++) {
  77.             if (!$frow.length) {
  78.                 break;
  79.             }
  80.             var $cell = $frow.children().eq(0);
  81.             $cell.addClass('week wn').text(date.getWeekNumber());
  82.             var iday;
  83.             for (var j = 0; j < 7; ++j, date.setDate(iday + 1)) {
  84.                 $cell = $cell.next();
  85.                 $cell.removeClass().data('nav', this.CONSTS.NAV['day']);
  86.                 if (!$cell.length) {
  87.                     break;
  88.                 }
  89.                 iday = date.getDate();
  90.                 $cell.text(iday);
  91.                 var current_month = (date.getMonth() == month);
  92.                 if (!current_month || j !=4 ) {
  93.                     $cell.addClass('oday').data('disabled',true);
  94.                     continue;
  95.                 }
  96.                 var disabled = false;
  97.                 if ((std != null && std > date) || (edd != null && edd < date)) {
  98.                     $cell.addClass('day disabled');
  99.                     disabled = true;
  100.                 } else {
  101.                     $cell.addClass('day');
  102.                 }
  103.                 $cell.data('disabled', disabled);
  104.                 if (!disabled) {
  105.                     if (current_month && iday == day) {
  106.                         this.cache.selectedDate && this.cache.selectedDate.removeClass('selected');
  107.                         $cell.addClass('selected');
  108.                         this.cache.selectedDate = $cell;
  109.                         this.cache.showDay = iday;
  110.                     }
  111.                     if (date.getFullYear() == TY &&
  112.                         date.getMonth() == TM &&
  113.                         iday == TD) {
  114.                         $cell.addClass('today');
  115.                     }
  116.                     var wday = date.getDay();
  117.                     if ([0, 6].indexOf(wday) != -1) {
  118.                         $cell.addClass("weekend");
  119.                     }
  120.                 }
  121.             }
  122.             $frow = $frow.next();
  123.         }
  124.     }
  125. if (FR.Browser.isIE8() && this.$view.css('visibility') == 'hidden') {
  126. this.$view.css("visibility", "visible");
  127. } else {
  128. this.$view.show();
  129. }
  130. $(document).bind('mousedown', this, this.collapseIf);
  131. this.modifyPosition();
  132. var tr = $('tbody>tr',this.datepicker.$datetable);
  133. for( var i=0; i<tr.length; i++ ){
  134. var $days = $('td[class!="week wn"]',tr);
  135. for( var j=0; j<$days.length; j++ ){
  136. var $day = $($days[j]);
  137. if( 4 != j && !$day.hasClass('oday')){
  138. $day.data("disabled",true);
  139. $day.attr('class','oday');
  140. }
  141. }
  142. }
  143. }
  144. 重点关注下面这段代码:

  145. var tr = $('tbody>tr',this.datepicker.$datetable);
  146. for( var i=0; i<tr.length; i++ ){
  147. var $days = $('td[class!="week wn"]',tr);
  148. for( var j=0; j<$days.length; j++ ){
  149. var $day = $($days[j]);
  150. if( 4 != j && !$day.hasClass('oday')){
  151. $day.data("disabled",true);
  152. $day.attr('class','oday');
  153. }
  154. }
  155. }
  156. 这段代码是只保留当月的每周周四可选,其他都不可选。

  157. 设置某一天不可选的方法为,获取到该天的 td 然后执行下面的代码:


  158. $day.data("disabled",true);
  159. $day.attr('class','oday');
复制代码


2.2 预览效果

保存报表,点击分页预览,报表效果如下图所示:


注:不支持移动端。


3. 模板下载

模板效果在线查看请点击:JS 实现日期控件的可选日期范围.cpt

已完成的模板,可参见:%FR_HOME%\webapps\webroot\WEB-INF\reportlets\doc\JS\参数界面JS实例\03-JS实现日期控件的可选日期范围.cpt

点击下载模板::03-JS实现日期控件的可选日期范围.cpt




编辑于 2020-12-14 18:47  
分享扩散:

沙发
发表于 2020-12-14 18:52:04 发布于APP客户端
支持
板凳
发表于 2020-12-14 18:52:48 发布于APP客户端
点击[http://img01.sogoucdn.com/app/a/200678/6159c4006f55535575cdd940d02448c4.jpg]查看表情
地板
发表于 2021-1-13 10:15:28
贴出来的代码,第一百148行,tr后面少了一个 [i]  和 cpt中代码不同
5楼
发表于 2021-4-15 15:49:08
如果能依数据库的日期来限制日期控件就更完美了
6楼
发表于 2021-8-4 17:27:23
大神,JS很差,如果想改成只选周一,怎么改?   只把这里改成1,只能当月生效,其他月还是周四
7楼
发表于 2022-3-18 11:24:39
CPT下载不了
8楼
发表于 2022-5-24 16:03:34

cpt 下载不了,自己改了一下 可以用,星期自己修改就可以,改2个数字就可以

9楼
发表于 2022-5-26 10:33:15
想要只能选择月底,要怎么改
10楼
发表于 2022-6-28 18:19:43
一个只要周末的,一个只有工作日的,这怎么改。。。。。。
11楼
发表于 2022-7-1 11:33:54

这是周末的

this._createCalendar = function(){
var o = this.options;
var self = this;
if (this.options.need2BuildConfig === true && this.options.data) {
this.options.data.resetStatus(this.createDependencePara4Data());
var data = this.options.data.getData();
if (data[0].data) {
if (data[0].data.startDate) {
var sd = new Date(data[0].data.startDate);
if (!FR.isInvalidDate(sd)) {
o.startDate = FR.date2Str(sd, 'yyyy-MM-dd');
this.std = this._createStartDate(o.startDate, o.format, this.viewMode);
}
}
if (data[0].data.endDate) {
var ed = new Date(data[0].data.endDate);
if (!FR.isInvalidDate(ed)) {
o.endDate = FR.date2Str(ed, 'yyyy-MM-dd');
this.edd = this._createEndDate(o.endDate, o.format, this.viewMode);
}
}
}
this.options.rebuildConfig = false;
}
this.datepicker = new FR.DatePicker({
renderEl: this.$view,
viewMode: this.viewMode,
date: FR.str2Date(this.editComp.val(), o.format),
dateFormat: o.format,
startDate: this.std,
endDate: this.edd,
onDateUpdate:function(){
if ($(':focus').length === 0) {
self.editComp.focus();
}
self.editComp.val(FR.date2Str(this.getValue(), o.format));
self.isValidateInput();
self.fireEvent(FR.Events.AFTEREDIT);
}
});
this.datepicker._loadDateData = function (table, date) {
        if (!date) {
            return;
        }
        var year = date.getFullYear(),
            month = date.getMonth(),
            day = date.getDate();
        var today = new Date(),
            TY = today.getFullYear(),
            TM = today.getMonth(),
            TD = today.getDate();
        this.cache.showYear = year;
        this.cache.showMonth = month;
        var std = this.options.startDate,
            edd = this.options.endDate;
        table.$title.text(Date._MN[month] + ", " + year);
        var nextDay = new Date(date);
        nextDay.setDate(nextDay.getMonthDays() + 1);
        if ((edd && nextDay > edd) || nextDay.getFullYear() > this.CONSTS.MAXYEAR) {
            table.$nextm.addClass('disabled').removeClass('hover').data('disabled', true);
        } else {
            table.$nextm.removeClass('disabled').data('disabled', false);
        }
        var prevDay = new Date(date);
        prevDay.setDate(0);
        if ((std && prevDay < std) || prevDay.getFullYear() < this.CONSTS.MINYEAR) {
            table.$prevm.addClass('disabled').removeClass('hover').data('disabled', true);
        } else {
            table.$prevm.removeClass('disabled').data('disabled', false);
        }
        date.setDate(1);
        var day1 = (date.getDay() - this.CONSTS.FIRSTDAY) % 7;
        date.setDate(0 - day1);
        date.setDate(date.getDate() + 1);
        var $frow = table.find('tbody').children().eq(0);
        for (var i = 0; i < 6; i++) {
            if (!$frow.length) {
                break;
            }
            var $cell = $frow.children().eq(0);
            $cell.addClass('week wn').text(date.getWeekNumber());
            var iday;
            for (var j = 0; j < 7; ++j, date.setDate(iday + 1)) {
                $cell = $cell.next();
                $cell.removeClass().data('nav', this.CONSTS.NAV['day']);
                if (!$cell.length) {
                    break;
                }
                iday = date.getDate();
                $cell.text(iday);
                var current_month = (date.getMonth() == month);
                if (!current_month || j !=6 || j !=0 ) {
                    $cell.addClass('oday').data('disabled',true);
                    continue;
                }
                var disabled = false;
                if ((std != null && std > date) || (edd != null && edd < date)) {
                    $cell.addClass('day disabled');
                    disabled = true;
                } else {
                    $cell.addClass('day');
                }
                $cell.data('disabled', disabled);
                if (!disabled) {
                    if (current_month && iday == day) {
                        this.cache.selectedDate && this.cache.selectedDate.removeClass('selected');
                        $cell.addClass('selected');
                        this.cache.selectedDate = $cell;
                        this.cache.showDay = iday;
                    }
                    if (date.getFullYear() == TY &&
                        date.getMonth() == TM &&
                        iday == TD) {
                        $cell.addClass('today');
                    }
                    var wday = date.getDay();
                    if ([0, 6].indexOf(wday) != -1) {
                        $cell.addClass("weekend");
                    }
                }
            }
            $frow = $frow.next();
        }
    }
if (FR.Browser.isIE8() && this.$view.css('visibility') == 'hidden') {
this.$view.css("visibility", "visible");
} else {
this.$view.show();
}
$(document).bind('mousedown', this, this.collapseIf);
this.modifyPosition();

var tr = $('tbody>tr',this.datepicker.$datetable);
for( var i=0; i<tr.length; i++ ){
var $days = $('td[class!="week wn"]',tr[i]);
for( var j=0; j<$days.length; j++ ){
var $day = $($days[j]);
if( 0 != j && 6 != j && !$day.hasClass('oday')){
$day.data("disabled",true);
$day.attr('class','oday');
}
}
}
}
12楼
发表于 2022-7-27 10:51:25

CustomJSError : Cannot read properties of undefined (reading '$datetable')

13楼
发表于 2022-8-19 14:43:44
跨月跨年控件就全部失效了
14楼
发表于 2022-8-25 14:25:13
决策报表可以用吗?
15楼
发表于 2022-9-21 14:34:49
我使用这个js后,为啥打开报表一段时间不操作后会自动将日期控件选中的值给清空呢?
16楼
发表于 2022-10-17 11:02:20

文档中模板下载无效,附件是从设计器里的示例文档

03-JS实现日期控件的可选日期范围.zip (2.96 K)

17楼
发表于 2022-10-19 11:50:27
决策报表能用吗
18楼
发表于 2023-4-24 12:00:16
大佬,求助,需要些一段js,把今天及今天之后的日期,全部置灰为不可选。
19楼
发表于 2024-2-22 14:42:31
按照代码为什么我的一打开是全部置灰的,切换下日期或者点下周天周一才出来限制的
20楼
发表于 2024-3-4 10:58:41
只能选昨天和每个月末的怎么修改呢
21楼
发表于 2024-3-30 14:44:42
求助,想实现起始日期只能选择前一个月之后的日期
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

31回帖数 24关注人数 16277浏览人数
最后回复于:2024-3-30 14:44

返回顶部 返回列表