关于用js实现的日历记事功能

博主是个java新手,目前在做的一个项目就是考勤排班系统,主要负责的模块是排班模块这一方面。需求上面要求要在显示当月的日历表,日历表上同时动态生成上班时间、下班时间、是否值班、值班类型等功能。
当时在网上找了很多日历模板,都没有找到能够符合自己要求的。便决定自己画一个页面。

样式没有做太多的美化 毕竟博主属于后端开发人员

个人感觉最主要的一块就是字符串的拼接,日历的生成,还有一些个别的属性需要注意。

基本样式引用:

<link rel="stylesheet" href="css/bootstrap.css" />
        <link rel="stylesheet" href="css/bootstrapValidator.css" />
        <link rel="stylesheet" href="css/css1.css" />
        <script type="text/javascript" src="js/jquery-1.10.2.js" ></script>
        <script type="text/javascript" src="js/bootstrap.js" ></script>
        <script type="text/javascript" src="js/bootstrapValidator.js" ></script>

html代码:

<div class="col-xs-10 col-xs-offset-1">
            <form class="form-inline">
              <div class="form-group col-xs-offset-1">
                <label for="exampleInputName2">部门:</label>
                <select class="form-control" style="margin-right: 50px;">

                    <option>==请选择==</option>
                    <option>产品研发部</option>
                    <option>系统运维部</option>
                    <option>人事管理部</option>

                </select>

                <label for="exampleInputEmail2">员工名:</label>
                <select class="form-control" style="margin-right: 100px;" onchange="alertdate()">

                    <option>==请选择==</option>
                    <option>张三</option>
                    <option>李四</option>
                    <option>王五</option>

                </select>
                <button class="btn btn-primary">保存</button>
              </div>

              <div class='calendar' id='calendar'></div>




            </form>


        </div>

html代码中的下拉框都是写死的,给第二个下拉框绑定onchange事件,触发事件在id=’calendar’的div中生成日历。

js部分:

var dateobj = prev();

            function prev(){
                var _date = new Date();    // 默认为当前系统时间
                return {
                  getDate : function(){
                    return _date;
                  },
                  setDate : function(date) {
                    _date = date;
                  }
                };
              }

            function alertdate(){

                renderhtml();    //对日历div中增加表格元素
                showCalendarData();  //在表格中显示日期
                bindEvent();   //对表格上方的上月下月绑定事件
                $(":radio").click(function(){

                    var parentCode=$(this).parent();
                    if($(this).val()=='true'){
                        if(parentCode.children("select").length==0){
                            parentCode.children("span").show();
                            parentCode.append("<select><option>白班</option><option>夜班</option></select>");
                        }
                    }else{

                        parentCode.children("select").remove();
                        parentCode.children("span").hide();

                    }
                });

            }


            function renderhtml(){
                var calendar=document.getElementById("calendar");
                var titlebox=document.createElement("div");  //在div中设置标题区  显示当前月份和上月下月的控制
                var bodybox=document.createElement("div");   //主体部分 用于存放日历表格

                titlebox.className="calendar-title-box";   //给标题box绑定属性   并向div中添加元素
                titlebox.innerHTML="<span id='prevMonth' class='prev-month'></span>"+
                "<span class='calendar-title' id='calendarTitle'></span>"+
                "<span class='next-month' id='nextMonth'></span>";

                 calendar.appendChild(titlebox);  //将标题box设为日历容器的子节点
                 bodybox.className='calendar-body-box';   //表格部分绑定属性
                 var headhtml="<tr>"+"<th>日</th>"+"<th>一</th>"+
                 "<th>二</th>"+"<th>三</th>"+"<th>四</th>"+
                 "<th>五</th>"+"<th>六</th>"+"</tr>";
                 var bodyhtml="";

                 for(var i=0;i<6;i++){      //一周7天 字符串拼接放到bodyhtml中
                    bodyhtml+="<tr>"+"<td></td>"+"<td></td>"+"<td></td>"+
                    "<td></td>"+"<td></td>"+"<td></td>"+"<td></td>"+"</tr>";
                 }
                 bodybox.innerHTML="<table id='calendarTable' class='table table-bordered text-center'>"+
                 headhtml+bodyhtml+"</table>";  //设置表格box的内容

                 calendar.appendChild(bodybox);

            }



            function showCalendarData(){
                //alert(dateobj);
                var year=dateobj.getDate().getFullYear();   //dateobj为object对象 通过getDate得到日期 再得到年
                var month=dateobj.getDate().getMonth()+1;
                var datestr=getdatestr(dateobj.getDate());  //通过函数gatdatestr将dateobj转换成字符串格式

                //设置表格顶部的年月信息
                var calendarTitle=document.getElementById("calendarTitle");
                var titleStr=datestr.substr(0,4)+"年"+datestr.substr(4,2)+"月";  //通过substr截取字符串  得到年的数字和月份数字
                calendarTitle.innerText=titleStr;   //将拼接后的****年**月显示在上方

                //设置表格中的日期数据
                var table=document.getElementById("calendarTable");
                var tds=table.getElementsByTagName("td");
                var firstday=new Date(year,month-1,1);  //当前月的第一天
                //alert(firstday.getDay());

                for(var i=0;i<tds.length;i++){
                    var thisday=new Date(year,month-1,i+1-firstday.getDay());  //getDay得到第一天是周几 从而显示第一行上个月的数据
                    var thisdayStr=getdatestr(thisday);
                    //tds[i].innerText=thisday.getDate();
                    tds[i].innerHTML="<span style='font-size:16px; font-wight:700'>"+thisday.getDate()+"</span>"+
                    "<br/>上班时间:<input type='text' style='width:48px; height:18px; margin-top:1px' placeholder='9:00' />"+
                    "<br/>下班时间:<input type='text' style='width:48px; height:18px; margin-top:1px' placeholder='18:00' />"+
                    "<br/>是否值班:<input type='radio' name='flag"+i+"' value='true' style='margin-top:2px' />是"+
                    "<input type='radio' name='flag"+i+"' value='false' checked='checked' style='margin-top:2px' />否"+
                    "<br/><span style='display:none'>值班类型:</span>";

                    tds[i].setAttribute("data",thisdayStr);
                    if(thisdayStr==getdatestr(new Date())){
                        tds[i].className="currentDay";   //当天设置属性
                    }else if(thisdayStr.substr(0,6)==getdatestr(firstday).substr(0,6)){
                        tds[i].className="currentMonth";  //当前月设置属性
                    }else{
                        tds[i].className="otherMonth";      //其他月的日历设置属性
                    }
                }

                //alert(dateobj.getdate().getDay());

            }


            function bindEvent(){
                var prevMonth=document.getElementById("prevMonth");
                var nextMonth=document.getElementById("nextMonth");
                addEvent(prevMonth,'click',toPrevMonth);    //绑定点击事件
                addEvent(nextMonth,'click',toNextMonth);
                //addEvent($(":radio"),'click',toChooseSch);
            }

            function getdatestr(date){
                var year=date.getFullYear();
                var month=date.getMonth()+1;  //月份从0开始
                var day=date.getDate();
                month=(month>9)?(""+month):("0"+month);  //如果得到的数字小于9要在前面加'0'
                day=(day>9)?(""+day):("0"+day);

                return year+month+day;
            }

            function addEvent(dom,eType,func){
                if(dom.addEventListener){
                    dom.addEventListener(eType,function(e){
                        func(e);
                    });
                }else if(dom.attachEvent){
                    dom.attachEvent('on'+eType,function(e){
                        func(e);
                    });
                }else{
                    dom['on'+eType]=function(e){
                        func(e);
                    }
                }
            }

            function toPrevMonth(){
                var date=dateobj.getDate();
                dateobj.setDate(new Date(date.getFullYear(),date.getMonth()-1,1));
                showCalendarData();
            }

            function toNextMonth(){
                var date=dateobj.getDate();
                dateobj.setDate(new Date(date.getFullYear(),date.getMonth()+1),1)
                showCalendarData();
            }

        </script>

其中印象比较深刻的地方有

1、每个单元格中的radio按钮所设置的checked=’checked’属性无效。
这个原因博主找了一会发现,因为所有的日历部分代码都是通过字符串拼接动态生成的,在生成radio按钮的时候

是否值班:<input type='radio' name='flag' value='true' style='margin-top:2px' />是
        <input type='radio' name='flag' value='false' checked='checked' style='margin-top:2px' />否

这里所绑定的name属性是全部相同的,即整个表格中的name属性重复,所以所生成的单选按钮组没有默认选中项。

后来在name属性中加上for循环中的变量i,实现一个单元格中的两个按钮name值相同,从而解决该问题。

2、相同类型的问题还有一处:

<span id='dutyType' style='display:none'>值班类型:</span>

博主在尝试实现选择值班时显示值班类型的功能时发现在js代码中无法找到该span。按理用jquery的id选择器不会出现这种问题啊,仔细想想应该还是字符串拼接出错。因为博主是使用for循环实现每个日历单元格都产生相应的操作,后面再根据是否属于当前月进行判断是进行显示还是隐藏。

最终发现每个单元格中所产生的span id全部相同,无法使用选择器找到。后来博主便放弃了使用id选择器的方法。改用节点操作:

$(":radio").click(function(){

                    var parentCode=$(this).parent();
                    if($(this).val()=='true'){
                        if(parentCode.children("select").length==0){
                            parentCode.children("span").show();
                            parentCode.append("<select><option>白班</option><option>夜班</option></select>");
                        }
                    }else{

                        parentCode.children("select").remove();
                        parentCode.children("span").hide();

                    }
                });

找到所点击按钮的父级元素,在父级元素的所有子元素中找到span的children,再通过hide或者show控制其显示或者隐藏。同样的select下拉框也是这样实现的。

3、字符串拼接后 radio按钮所绑定的click事件失效。

$(":radio").click(function(){

                    var parentCode=$(this).parent();
                    if($(this).val()=='true'){
                        if(parentCode.children("select").length==0){
                            parentCode.children("span").show();
                            parentCode.append("<select><option>白班</option><option>夜班</option></select>");
                        }
                    }else{

                        parentCode.children("select").remove();
                        parentCode.children("span").hide();

                    }
                });

还是相同的代码块,原先博主是用html()方法获取所点击按钮父级元素中所有的内容,在后面继续字符串的拼接加上select下拉框,最后再用html()将原先的内容替换,但是后面自测发现事件失效,当前单元格中的click事件无效,在Google的开发者工具中查看页面代码无问题,但是始终不能触发事件。

后选择是用append的方法实现。查阅相关资料应该是js部分的代码在页面加载完之后,也随之加载完,若想再次实现点击事件需要重新加载js代码,看的我一脸懵逼。这地方始终不是太明白。

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 65
    评论
评论 65
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值