背景:
近期,公司的產品經常會遇到日期排班類似的功能;
需求的排班日期長短不一:有些是兩周,有些是四周;要求選中的時候有一個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
