Javascript:日期排班功能实现

 

 背景:

 近期,公司的产品经常会遇到日期排班类似的功能;

 需求的排班日期长短不一:有些是两周,有些是四周;要求选中的时候有一个active的状态区分,另外要提供钩子获取选中日期的形如:【2018-04-11】这种格式的数据。

 

实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
 * 获取当天及之后的排班时间
 * @param dayCount:相对于今天的天数,形如:0,1,2.......
 */
function getDateData(dayCount) {
    var d = new Date();
    d.setDate(d.getDate() + dayCount);
    var y = d.getFullYear();
    var m = (d.getMonth() + 1) > 9 ? d.getMonth() + 1 : '0' + (d.getMonth() + 1);
    var d = d.getDate() > 9 ? d.getDate() : '0' + d.getDate();
    return y + "-" + m + "-" + d;
}
/*
 * 获取日期对应的星期名称
 * @param date:待转换日期,形如:'2018-04-11' 或 '2018-4-11'
 */
function dateToDay(date) {
    var dayNo = new Date(date).getDay();
    switch (dayNo) {
        case 0:
            return '星期日';
            break;
        case 1:
            return '星期一';
            break;
        case 2:
            return '星期二';
            break;
        case 3:
            return '星期三';
            break;
        case 4:
            return '星期四';
            break;
        case 5:
            return '星期五';
            break;
        case 6:
            return '星期六';
            break;
        default:
            break;
    }
}
/*
 * 通过参数动态获取排班日期
 * @param weekCount:排班周数,int型
 * @param domId: 输出DomId
 */
function initWeekData(weekCount, domId) {
    var weekDateTempl = '',
        tableTempl = '',
        tableTh = '',
        tableTd = '',
        tableTdArr = [],
        weekData = [],
        weekDataFinal = [],
        weekDateEle;
    for (var i = 0; i < weekCount * 7; i++) {
        weekData[i] = getDateData(i);
    }
    for (var i = 0; i < weekData.length; i = i + 7) {
        weekDataFinal.push(weekData.slice(i, i + 7));
    }
    weekDataFinal.forEach(function(item, index) {
        if (index === 0) {
            for (var i = 0; i < item.length; i++) {
                tableTh += '<th>' + dateToDay(item[i]) + '</th>'
            }
            tableTh = '<tr>' + tableTh + '</tr>';
            //firstWeek
            for (var j = 0; j < item.length; j++) {
                if (j === 0) {
                    tableTd += '<td attr-date=' + item[j] + ' class="active">今天</td>';
                } else {
                    tableTd += '<td attr-date=' + item[j] + '>' + new Date(item[j]).getDate() + '</td>';
                }
            }
            tableTd = '<tr>' + tableTd + '</tr>';
            tableTdArr[index] = tableTd;
            tableTd = '';
        } else {
            for (var k = 0; k < item.length; k++) {
                tableTd += '<td attr-date=' + item[k] + '>' + new Date(item[k]).getDate() + '</td>';
            }
            tableTd = '<tr>' + tableTd + '</tr>';
            tableTdArr[index] = tableTd;
            tableTd = '';
        }
    });
    tableTempl = tableTh + tableTdArr.join('');
    weekDateEle = document.querySelector('#' + domId);
    weekDateEle.innerHTML = tableTempl;
    weekDateEle.querySelectorAll('tr>td').forEach(function(item, index) {
        item.addEventListener("click", function() {
            weekDateEle.querySelectorAll('tr>td').forEach(function(item, index) {
                item.classList.remove('active');
            });
            this.classList.add('active');
            alert(this.getAttribute('attr-date'))
        });
    });
}

  

调用实例:

1
2
3
4
//调用实例
initWeekData(2, 'twoWeekDate');
 
initWeekData(4, 'fourWeekDate');

 

实现效果:

线上DEMO:

https://codepen.io/kevinInsight/pen/mxoOaz

 

-------------------------------- 间隔线 --------------------------------

 

后来过了一段时间,需要一个如下图所示的排班:

 

要求:星期title固定;指定月份第一天如果不是周一,则前面置空;最后一天如果不是周日,则后面置空;已经排版的日期,加一个激活态(active),点击可以查看具体时间(如:2019-2-14)

 实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
       * 获取当天及之后的排班时间
       * @param month:指定的月份
       * @param dayCount:相对于今天的天数,形如:0,1,2.......
       */
      function getDateData(month, dayCount) {
          let yy, mm, dd;
          let d = new Date();
          let initDay = d.getFullYear() + '-' + month + '-01';
          d = new Date(initDay);
          d.setDate(d.getDate() + dayCount);
          yy = d.getFullYear();
          mm = (d.getMonth() + 1) > 9 ? d.getMonth() + 1 : '0' + (d.getMonth() + 1);
          dd = d.getDate() > 9 ? d.getDate() : '0' + d.getDate();
          return yy + "-" + mm + "-" + dd;
      }
 
      /*
       * 根据月份查询排班结果
       * @param month: 指定月份,整型数字1-12
       */
 
      function schedueByMonth(month) {
          let dates = [],
              weekData = [],
              weekDataFinal = [],
              d, m, w, weekNum, lastWeek, lastWeekDiff = [];
          let formatMonth = month > 9 ? month : '0' + month;
          for (let i = 0; i <= 31; i++) {
              d = getDateData(formatMonth, i);
              m = new Date(d).getMonth() + 1;
              if (m === month) {
                  dates.push(d)
              }
          }
          w = new Date(dates[0]).getDay();
          if (w > 0) {
              for (let j = 0; j < w - 1; j++) {
                  dates.unshift('')
              }
          } else if (w === 0) {
              for (let j = 0; j < 6; j++) {
                  dates.unshift('')
              }
          }
          //dates分组:每组7天
          for (let i = 0; i < dates.length; i = i + 7) {
              weekDataFinal.push(dates.slice(i, i + 7));
          }
          //最后一行不够7个,则补齐
          lastWeek = weekDataFinal[weekDataFinal.length - 1];
          if (lastWeek.length < 7) {
              for (let k = 0; k < (7 - lastWeek.length); k++) {
                  lastWeekDiff.push('')
              }
              lastWeek = lastWeek.concat(lastWeekDiff)
              weekDataFinal[weekDataFinal.length - 1] = lastWeek;
          }
          pendingWeekData(dates, weekDataFinal)
      }
 
      function pendingWeekData(dates, weekDataFinal) {
          let weekTitles = '<tr><td>星期一</td><td>星期二</td><td>星期三</td><td>星期四</td><td>星期五</td><td>星期六</td><td>星期日</td></tr>';
          let scheduDom = '',
              weeksDom = '',
              weekDom = '';
          weekDataFinal.forEach(function(item) {
              item.forEach(function(subItem) {
                  weekDom += '<td attr-date="' + subItem + '">' + delWithDay(subItem) + '</td>';
              })
              weeksDom += '<tr>' + weekDom + '</tr>';
              weekDom = '';
          })
          scheduDom = weekTitles + weeksDom;
          $('#schedue').html(scheduDom);
 
          //加入业务数据
          let date = ['2019-12-07', '2019-12-12', '2019-12-31']; //date为接口返回的排班时间,形如:['2019-12-07', '2019-12-12', '2019-12-28']
          delWithSchedue(dates, date)
      }
 
      function delWithSchedue(dates, date) {
          let pesoDates = date; //date为接口返回的排班时间
          let index;
          if (pesoDates.length > 0) {
              pesoDates.forEach(function(item, index) {
                  index = dates.indexOf(item)
                  $('#schedue').find('td').eq(index + 7).addClass('active').click(function() {
                      alert($(this).attr('attr-date'))
                  })
              })
          }
      }
 
      function delWithDay(day) {
          if (day) {
              return new Date(day).getDate()
          } else {
              return ''
          }
      }
      //调用实例
      schedueByMonth(12)

  

线上DEMO:

https://codepen.io/kevinInsight/pen/omPeMM

 

   

 

posted @   Me-Kevin  阅读(5974)  评论(9编辑  收藏  举报
编辑推荐:
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
· 对象命名为何需要避免'-er'和'-or'后缀
· SQL Server如何跟踪自动统计信息更新?
阅读排行:
· “你见过凌晨四点的洛杉矶吗?”--《我们为什么要睡觉》
· C# 从零开始使用Layui.Wpf库开发WPF客户端
· 提示词工程师自白:我如何用一个技巧解放自己的生产力
· C#/.NET/.NET Core技术前沿周刊 | 第 31 期(2025年3.17-3.23)
· 编程神器Trae:当我用上后,才知道自己的创造力被低估了多少
点击右上角即可分享
微信分享提示