Javascript:日期排班功能实现

 

 背景:

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

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

 

实现:

        
        /*
         * 获取当天及之后的排班时间
         * @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'))
                });
            });
        }

  

调用实例:

   //调用实例
   initWeekData(2, 'twoWeekDate');

   initWeekData(4, 'fourWeekDate');

 

实现效果:

线上DEMO:

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

 

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

 

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

 

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

 实现:

  /*
         * 获取当天及之后的排班时间
         * @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

 

   

 

转载于:https://www.cnblogs.com/kevinCoder/p/8794480.html

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
全自动表使用说明 1、在设置好年份与表头。 "2、每年1月1日,在中按一个周期设置好人员名单,将自动生成全年表,   第一行就是1月1日上人员,如使用该表时不是1月1日,可以通过调整中   的次序来获得之后日期的正确表。单元格内的多行人员代表当天几个   (如三行就是早中晚),当天增加一个,就在人员单元格内按[Alt-Enter]换行。" 3、在表中,请自行增加本年的节日,假日会以红底黑字增亮显示 4、在中设置好次与工时。 5、在中可以自动统计每人每月或全年的工作量 "6、对于不规则情况的,如换,可以在当月人员名单中手动更改,另外,如果每天   的次大于三个,会出现单元格显示不下的情况,这时可以用快捷键来修改字体大小。" "7、快捷键:   Ctrl-q 所有表保护状态,只有人员显示栏可以更改   Ctrl-e 取消所有表的保护状态,所有栏都可编辑   Ctrl-r 所有表人员名称字体加大   Ctrl-t 所有表人员名称字体减小 Ctrl-p 下打印表 Alt-F4 退出EXECL" "8、注意事项:理论上没有限制,但由于单元格显示宽高度有限(字体太小影响显示效果),       本表建议适用一个最多三人,一天最多四个(四行)的情况,不符合       该条件的可以使用《表(考勤版)》解决。"

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值