Javascript:日期排班功能实现
Posted kevinInsight
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
以上是关于Javascript:日期排班功能实现的主要内容,如果未能解决你的问题,请参考以下文章