• 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

       

  • 相关阅读:
    获取当前时间并格式化,CTime类
    疑问:VS在调试的过程中,总是会提示正在加载picface.dll的符号,然后卡死在那
    Markup解析XML——文档,说明
    .net Core 获取当前程序路径
    Excel中的细节
    心血来潮尝试一个小项目(WinForm)
    bat文件以管理员运行
    DataGridView一些总结
    常见辅助类、方法
    向txt文件中添加或者追加文字字符串
  • 原文地址:https://www.cnblogs.com/kevinCoder/p/8794480.html
Copyright © 2020-2023  润新知