近期看到个需求,“配置一年的工作日”。青铜五coder手动撸了一个,效果图如下(截了上半部分),打钩了的就是工作日。
边说思路,边贴码。
每个月都是用一个<table>实现的,用循环的方式遍历出十二个<table>出来,或者手动撸十二下,,,
数据格式是一数组,长度365或366,“0”表示“非工作日”,“1”表示“工作日”,如:
[0,0,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,1,1,1,1,1,0,0,0,0,0,0,0,1,1,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,1,0,0,0,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,0,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,1,0,0,0,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0,0]
每个<table>有6行*7列为42个格子,12个<table>就有504个格子也就是<td>,需要做文章。头几格和后几格都不属于本月的日子,暂且叫“非日期”吧,中间的都是“日期”格子,主要就是要在这些日期格子里循环生成数字和复选框。如下图,红色格子为“非日期”。
这些“日期”和“非日期”,用一个数组来表示,“0”表示“非日期”,“1”表示“日期”,如下这一串表示2017年一月份的情况。生成代码如下下(Java)。
[0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0]
ArrayList<Integer> date = new ArrayList<>();
int x = 31;// 每个月有几天
int y = 7;// 每个方框前面空几格
for (int j = 0; j < 42; j++) {
// “非日期”用“0”表示
if (j < y) {
date.add(0);
continue;
}
// 周末部分,用“2”表示
// if (x != 0 && (j == 0 || j == 6 || j == 7 || j == 13 || j == 14
// || j == 20 || j == 21 || j == 27 || j == 28
// || j == 34 || j == 35)) {
// date.add(2);
// x--;
// continue;
// }
// “日期”用“1”表示
if (x != 0) {
date.add(1);
x--;
continue;
}
date.add(0);
}
// 打印出来看看
// System.out.println(date);
十二个月的话就循环,自己手动优化下,把x和y改成数组,记录每个月实际情况,在生成。
下面是生成页面日期和复选框,以及勾选复选框的js,主要是做好条件判断即可。
function print(json){//json是上面说到记录365或366里的工作日的数组
var i = 0;//计数,记录当前遍历到第几个格子,最大值为504
var j = 0;//每个月第几日,最大值由k数组控制
var k = [31,28,31,30,31,30,31,31,30,31,30,31];//十二个月,每个月最大天数
var l = -1;//数组k的索引
var m = 0;//2017年365天计数,记录当前遍历到2017年的第几天
//2017年日历,6行*7列*12个月,504个格子的数组,(不含节假日)0:非日期;1:工作日;2:周末,有没有周末的标识无所谓
var date = [0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 0, 0, 0, 0,
0, 0, 0, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 0, 0, 0, 0, 0,
0, 0, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 0, 0, 0, 0,
0, 0, 0, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 0, 0, 0, 0, 0, 0];
//获取table下说有的td元素,做遍历
$(".table").find("td").each(function(){
if((i)%42==0){//计数i能被42整除,数组k的索引l,自加1
l++;
}
if(j==k[l]){//每月第几日计数j,达到最高天数,j重置为0
j=0;
}
if(date[i]!=0){//只要date[i]不等于0,说明是“日期”格子,这时放入日期和复选框
var checked;
j++;//每月第几日自加1
if(json[m]!=0){
checked = 'checked="checked"';
}
m++;//365天计数自加1
$(this).html(j+"<br>"+"<input type='checkbox' name='workday' value='"+m+"' "+checked+">");
}
i++;
});
}
前台还有从后台获取数据方面的就不贴出来了,下面说下提交后后端处理数据。
所有“checkbox”的“name”都是“workday”,“value”就是1-365或366,用个数组装好他们,然后该怎么处理就怎么处理咯。获取到的数组大致如下,就是一年的第几天第几天是工作日。
[3, 4, 5, 6, 9, 10, 11, 12, 13, 16, 17, 18, 19, 20, 22, 23, 24, 25, 26, 34, 35, 37, 38, 39, 40, 41, 44, 45, 46, 47, 48, 51, 52, 53, 54, 55, 58, 59, 60, 61, 62, 65, 66, 67, 68, 69, 72, 73, 74, 75, 76, 79, 80, 81, 82, 83, 86, 87, 88, 89, 90, 91, 95, 96, 97, 100, 101, 102, 103, 104, 107, 108, 109, 110, 111, 114, 115, 116, 117, 118, 122, 123, 124, 125, 128, 129, 130, 131, 132, 135, 136, 137, 138, 139, 142, 143, 144, 145, 146, 147, 151, 152, 153, 156, 157, 158, 159, 160, 163, 164, 165, 166, 167, 170, 171, 172, 173, 174, 177, 178, 179, 180, 181, 184, 185, 186, 187, 188, 191, 192, 193, 194, 195, 198, 199, 200, 201, 202, 205, 206, 207, 208, 209, 212, 213, 214, 215, 216, 219, 220, 221, 222, 223, 226, 227, 228, 229, 230, 233, 234, 235, 236, 237, 240, 241, 242, 243, 244, 247, 248, 249, 250, 251, 254, 255, 256, 257, 258, 261, 262, 263, 264, 265, 268, 269, 270, 271, 272, 273, 282, 283, 284, 285, 286, 289, 290, 291, 292, 293, 296, 297, 298, 299, 300, 303, 304, 305, 306, 307, 310, 311, 312, 313, 314, 317, 318, 319, 320, 321, 324, 325, 326, 327, 328, 331, 332, 333, 334, 335, 338, 339, 340, 341, 342, 345, 346, 347, 348, 349, 352, 353, 354, 355, 356, 359, 360, 361, 362, 363]
String[] workdayStr = request.getParameterValues("workday");
ArrayList<Integer> workdays = new ArrayList<>();
if (Misc.isNotEmpty(workdayStr)) {//这个是自己写的,用来检查是否“null”用的,代码要“健壮”嘛,,,
for (int i = 0; i < dateCount; i++) {//“dateCount”是上面的定义的,就是一年的天数365或者366
workdays.add(0);//反正就是先装一个长度为365/366的,全部是“0”的数组
}
for (String str : workdayStr) {
int date = Integer.parseInt(str);
workdays.set(date - 1, 1);//然后把对应属于工作日的,替换成1就行了。
}
}
//当然也可以定义全部是“1”的数组,然后把“0”替换上去,减少循环次数
以上差不多是核心部分啦,写完之后,是时候去找找看看有没有别人已经写好的组件啥的了,找到我再贴过来。