fullCalendar改造计划之带农历节气节假日的万年历(转)

fullCalendar改造计划之带农历节气节假日的万年历(转)

http://feifei.im/archives/168

计划着要做一款万年历,作为自己小项目的便民功能。

作为一枚“资深”业余前端,本想着网上应该有现成的代码可用,一顿猛搜之后,倒是确实搜到几个,但是一看功能,跟我想的不一样;再看代码,顿时没有了修改的欲望。顿时大失所望,理想太丰满,现实太骨感啊!!

无意搜到一款jquery的日程安排日历插件,fullCalendar(官网:http://arshaw.com/fullcalendar/),

发现嗯,功能貌似挺强大的嘛,再一看,最近更新日期是2013年9月,于是决定了,改造!

下载下来的最新版是fullcalendar-1.6.4,原生的样子是这样的: 请输入图片描述

但是我想象的应该是这个样子的: 请输入图片描述

貌似差别有点大……没关系,一步步来改造。

一、当然是汉化啦

需要汉化的地方不多,就一些英文的月份,周几而已,简单修改一下

  1. // locale
  2. isRTL: false,
  3. firstDay: 0,
  4. monthNames: ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'],
  5. monthNamesShort: ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'],
  6. dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'],
  7. dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'],
  8. buttonText: {
  9. prev: "<span class='fc-text-arrow'>&lsaquo;</span>",
  10. next: "<span class='fc-text-arrow'>&rsaquo;</span>",
  11. prevYear: "<span class='fc-text-arrow'>&laquo;</span>",
  12. nextYear: "<span class='fc-text-arrow'>&raquo;</span>",
  13. today: '返回今天',
  14. month: '月',
  15. week: '周',
  16. day: '日'
  17. },

按钮显示的内容,除了可以直接改源文件之外,也可以在页面的初始化js中配置“buttonText”的值,比如:

  1. buttonText: {
  2. prev: "<span class='fc-text-arrow'>&lsaquo;上个月</span>",
  3. next: "<span class='fc-text-arrow'>下个月&rsaquo;</span>",
  4. prevYear: "<span class='fc-text-arrow'>&laquo;上一年</span>",
  5. nextYear: "<span class='fc-text-arrow'>下一年&raquo;</span>"
  6. },

简单汉化后就成了这样: 请输入图片描述

二、添加农历,节气,节假日的信息显示

作为一款万年历,没有这些中国特色的东西,出门都不好意思说自己是日历。

要显示这些农历,节假日信息,有两种方法:

一是直接调用google calendar的订阅地址,把这些信息通过配置fullCalendar自带的events的方式,像显示日程安排一样显示出来,fullCalendar是原生支持google calendar调用的(不过貌似只能调一个文件);

比如官方示例里的显示美国节假日的例子:

  1. // US Holidays
  2. events: 'http://www.google.com/calendar/feeds/usa__en%40holiday.calendar.google.com/public/basic'

换一下源地址中的ID部分,就可以显示其他日程,比如:

  1. 中国节假日(Calendar ID: china__zh_cn@holiday.calendar.google.com);
  2. 农历(Calendar ID: lunar__zh_cn@holiday.calendar.google.com);

二是直接修改源文件,这个相对第一种直接调相对麻烦些,不过好处就是可以完全自定义,想怎样就怎样……毫无疑问,作为一个患有轻微代码强迫症的程序猿,果断选择自己修改源文件,至于events方式,就留着以后用来显示假期安排吧。

既然要自定义,那就需要一个节气节假日以及农历信息的库,比较了一下各大导航站(因为导航站一般都有万年历……),在hao123扒到一个看起来不错的js库(点我查看lunar.js),包含了农历,节气和节假日。嗯……hao123的日历风格貌似也挺不错,OK,就它了!

为了方便,直接把lunar.js的内容拷到fullCalendar的js文件fullCalendar.js里;然后就可以修改显示日期的单元格的内容和样式啦。直接贴修改的代码:

  1. if (showNumbers) {
  2. html += "<div class='fc-day-number'>" + date.getDate() + "</div>";
  3. // modified by feifei.im 增加节气显示
  4. var cTerm = lunar(date).term;
  5. if(cTerm){
  6. html += "<div class='fc-day-cnTerm'>"+cTerm+"</div>";
  7. }
  8. // modified by feifei.im 增加节日显示
  9. var fes = lunar(date).festival();
  10. if(fes && fes.length>0){
  11. html += "<div class='fc-day-cnTerm'>"+$.trim(fes[0].desc)+"</div>";
  12. }
  13. // modified by feifei.im 无节日节气时,增加农历显示
  14. if(!cTerm && (!fes || fes.length==0)){
  15. html += "<div class='fc-day-cnDate'>"+lunar(date).lMonth + "月" + lunar(date).lDate +"</div>";
  16. }
  17. }

这边为了保持整齐,如果当前日期有节气或者节假日的话,就不显示农历了

OK,现在节气节假日已经可以显示了 请输入图片描述

三、添加年月下拉框,方便选择日期

现在的日历大体功能已经实现了,但是有一点比较影响用户体验:现在要是想看几年前或者几个月前的日期,必须一次次的点“上一年”,“上个月”的按钮,直到点到需要的日期。一两年也就罢了,十几二十年的话就纠结了……

所以,添加一个下拉框用来显示并选择当前年月信息还是很有必要滴……

方便起见,直接把fullCalendar的“title”部分修改成下拉框(也就是下图显示的这个部分): 修改成下拉框

直接贴代码:

1.修改title的内容,原生的是直接显示文字,改成下拉框的形式

  1. $.each(this.split(','), function(j, buttonName) {
  2. if (buttonName == 'title') {
  3. //e.append("<span class='fc-header-title'><h2>&nbsp;</h2></span>");
  4. // modified feifei.im 下拉框选择年月
  5. var selectHtml = '';
  6. var i = 0;
  7. selectHtml +="<span id='fc-dateSelect' class='fc-header-title'>";
  8. selectHtml +="<select name='fcs_date_year' id='fcs_date_year' class='selectable m_year mr15'>";
  9. // 循环年份
  10. for(i=1901;i<=2100;i++){
  11. selectHtml +="<option value='"+i+"'>"+$.trim(i+"年")+"</option>";
  12. }
  13. selectHtml +="</select>";
  14. selectHtml +="<select name='fcs_date_month' id='fcs_date_month' class='selectable m_year'>";
  15. // 循环月份
  16. var monthDigitCN = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '十一', '十二'];
  17. for(i=0;i<=11;i++){
  18. selectHtml +="<option value='"+i+"'>" +$.trim(monthDigitCN[i]+"月") + "</option>";
  19. }
  20. selectHtml +="</select>";
  21. selectHtml +="</span>";
  22. e.append(selectHtml);
  23. if (prevButton) {
  24. prevButton.addClass(tm + '-corner-right');
  25. }
  26. prevButton = null;
  27. }

2.修改原title更新方法,之前是修改title的文本,改成修改下拉框的选中值

  1. function updateTitle(html) {
  2. //element.find('h2').html(html);
  3. // modified feifei.im 更新title时修改为下拉框
  4. var shtm = html.split(" ");
  5. if(shtm && shtm.length>1){
  6. $("#fcs_date_month").find("option").filter(function(){
    return ($(this).text() == $.trim(shtm[0]));}).prop('selected', true);
  7. $('#fcs_date_year option[value="'+$.trim(shtm[1])+'"]').prop('selected', true);
  8. }
  9. }
  1. 这边有个坑,网上流传的根据selecttext值修改select的选中状态的代码根本没用啊!!
  2. 就是这货$(‘#fcs_date_month option[text=”‘+$.trim(shtm[1])+‘”]’).attr(‘selected’, true);
  3. 后来改成上面的“$(“#fcs_date_month”).find(“option”).filter……”这种实现方式才可以

3.此时下拉框已经能随着当前月份年份的变化自动改变选中的值,但是用户自己选择年份月份的时候还是没有任何反应的……所以得给下拉框绑定相应的响应事件

由于下拉框是动态生成的,所以用delegate来绑定,并调用fullCalendar插件自带的跳转到某个日期的方法“gotoDate”。

代码如下

  1. /** 绑定事件到日期下拉框 **/
  2. $(function(){
  3. $("#fc-dateSelect").delegate("select","change",function(){
  4. var fcsYear = $("#fcs_date_year").val();
  5. var fcsMonth = $("#fcs_date_month").val();
  6. $("#calendar").fullCalendar('gotoDate', fcsYear, fcsMonth);
  7. });
  8. });

4.OK,下拉框显示并选择日期功能改造成功

四、添加日期详细信息显示

经过简单改造,fullCalendar已经可以满足要求了,不过为了更好的用户体验嘛,可以加上一个显示当天日期的详细信息(天干地支,生肖节气什么的)的功能(好吧,我会告诉你我是赤果果的在抄hao123么……)

老规矩,直接贴代码:

官方示例里,只有一个

  1. <div id="calendar"></div>

用来显示日历控件的相关内容,现在我们把它扩展下,加点东西

  1. <!-- 加载提示 -->
  2. <div id="msgTopTipWrapper">
  3. <div id="msgTopTip">
  4. <span><i class="iconTip"></i>正在载入日历数据...</span>
  5. </div>
  6. </div>
  7. <div class="calendarWrapper">
  8. <!-- 日期详细信息 -->
  9. <div class="rightSidePanel mb50 fr">
  10. <div id="div_day_detail" class="h_calendar_alm">
  11. <div class="alm_date"></div>
  12. <div class="alm_content nofestival">
  13. <div class="today_icon"></div>
  14. <div class="today_date"></div>
  15. <p id="alm_cnD"></p>
  16. <p id="alm_cnY"></p>
  17. <p id="alm_cnA"></p>
  18. <div class="alm_lunar_date"></div>
  19. </div>
  20. </div>
  21. </div>
  22. <!-- 日历主体 -->
  23. <div id="calendar" class="dib"></div>
  24. </div>

然后加上页面加载时初始化今日详细信息的js代码:

  1. /** 当天信息初始化 **/
  2. $(function(){
  3. var dayDate = new Date();
  4. var d = $.fullCalendar.formatDate(dayDate,"dddd");
  5. var m = $.fullCalendar.formatDate(dayDate,"yyyy年MM月dd日");
  6. var lunarDate = lunar(dayDate);
  7. $(".alm_date").html(m + "&nbsp;" + d);
  8. $(".today_date").html(dayDate.getDate())
  9. $("#alm_cnD").html("农历"+ lunarDate.lMonth + "月" + lunarDate.lDate);
  10. $("#alm_cnY").html(lunarDate.gzYear+"年&nbsp;"+lunarDate.gzMonth+"月&nbsp;"+lunarDate.gzDate+"日");
  11. $("#alm_cnA").html("【"+lunarDate.animal+"年】");
  12. var fes = lunarDate.festival();
  13. if(fes.length>0){
  14. $(".alm_lunar_date").html($.trim(lunarDate.festival()[0].desc));
  15. $(".alm_lunar_date").show();
  16. }else{
  17. $(".alm_lunar_date").hide();
  18. }
  19. });

加上对应的css样式后,现在刷新页面已经可以看到当天的详细信息了,但是我们需要可以查看每天的详细信息,所以要给日期的单元格加上对应的触发时间,fullCalendar已经有这功能了,配置一下就OK,同时顺便配置一下加载提示信息的显示与隐藏:

  1. dayClick : function(dayDate, allDay, jsEvent, view) {
    //点击单元格事件
  2. var d = $.fullCalendar.formatDate(dayDate,"dddd");
  3. var m = $.fullCalendar.formatDate(dayDate,"yyyy年MM月dd日");
  4. var lunarDate = lunar(dayDate);
  5. $(".alm_date").html(m + "&nbsp;" + d);
  6. $(".today_date").html(dayDate.getDate())
  7. $("#alm_cnD").html("农历"+ lunarDate.lMonth + "月" + lunarDate.lDate);
  8. $("#alm_cnY").html(lunarDate.gzYear+"年&nbsp;"+lunarDate.gzMonth+"月&nbsp;"+lunarDate.gzDate+"日");
  9. $("#alm_cnA").html("【"+lunarDate.animal+"年】");
  10. var fes = lunarDate.festival();
  11. if(fes.length>0){
  12. $(".alm_lunar_date").html($.trim(lunarDate.festival()[0].desc));
  13. $(".alm_lunar_date").show();
  14. }else{
  15. $(".alm_lunar_date").hide();
  16. }
  17. // 当天则显示“当天”标识
  18. var now = new Date();
  19. if (now.getDate() == dayDate.getDate() && now.getMonth() == dayDate.getMonth() && now.getFullYear() == dayDate.getFullYear()){
  20. $(".today_icon").show();
  21. }else{
  22. $(".today_icon").hide();
  23. }
  24. },
  25. loading : function(bool) {
  26. if (bool)
  27. $("#msgTopTipWrapper").show();
  28. else
  29. $("#msgTopTipWrapper").fadeOut();
  30. }

至此,改造之后的fullCalendar已经满足要求啦。至此基本改造完成,下一步的目标是要在日历上显示节假日的放假上班安排,这个可以通过fullCalendar的events配置,后端生成相应json来实现。

配置很简单,就是之前配置events的方法,只不过地址换成自己的:

  1. events : "${ctx}/topic/rili/getFestival",

然后后端对应的返回相应的json串即可,比如我用的springMVC就这么搞:

  1. @ResponseBody
  2. @RequestMapping(value="/topic/rili/getFestival",method = RequestMethod.GET)
  3. public List<Map<String,Object>> riLiGetFestival() {
  4. List<Map<String,Object>> festivalList = new ArrayList<Map<String,Object>>();
  5. // 2014全部假期日期表
  6. String holidayTitles = "春节假期;清明节假期;劳动节假期;端午节假期;中秋节假期;国庆节假期;元旦假期;春节调休上班;春节调休上班;劳动节调休上班;国庆节调休上班";
  7. String holidayStarts = "2014-1-31;2014-4-5;2014-5-1;2014-5-31;2014-9-6;2014-10-1;2014-1-1;2014-1-26;2014-2-8;2014-5-4;2014-9-28;2014-10-11";
  8. String holidayEnds = "2014-2-6;2014-4-7;2014-5-3;2014-6-2;2014-9-8;2014-10-7;2014-1-1;2014-1-26;2014-2-8;2014-5-4;2014-9-28;2014-10-11";
  9. String[] arrHolidayTitles = holidayTitles.split(";");
  10. String[] arrHolidayStarts = holidayStarts.split(";");
  11. String[] arrHolidayEnds = holidayEnds.split(";");
  12. for (int i=arrHolidayTitles.length-1;i>=0;i--){
  13. Map<String,Object> map = new HashMap<String,Object>();
  14. map.put("id", i);
  15. map.put("title", arrHolidayTitles[i]);
  16. map.put("start", arrHolidayStarts[i]);
  17. map.put("end", arrHolidayEnds[i]);
  18. festivalList.add(map);
  19. }
  20. return festivalList;
  21. }

这样就能显示假期信息

转载于:https://www.cnblogs.com/huideng/p/4670278.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/109392.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 前端UI框架整理

    前端UI框架整理1 TDesign 腾讯最近刚刚公开的一套 UI 框架 个人感觉不错 下面是官网介绍 TDesign 是什么 TDesign 是腾讯各业务团队在服务业务过程中沉淀的一套企业级设计体系 TDesign 具有统一的设计价值观 一致的设计语言和视觉风格 帮助用户形成连续 统一的体验认知 在此基础上 TDesign 提供了开箱即用的 UI 组件库 设计指南和相关设计资产 以优雅高效的方式将设计和研发从重复劳动中解放出来 同时方便大家在 TDesign 的基础上扩展 更好的的贴近业务需求 为什么会有 TDe

    2025年9月23日
    6
  • python解压bz2文件命令,在Python中解压缩.bz2文件

    python解压bz2文件命令,在Python中解压缩.bz2文件So,thisisaseeminglysimplequestion,butI’mapparentlyveryverydull.Ihavealittlescriptthatdownloadsallthe.bz2filesfromawebpage,butforsomereasonthedecompressingofthatfile…

    2022年5月31日
    188
  • ch340转485电路图_ch340c芯片手册

    ch340转485电路图_ch340c芯片手册CH340可以实现USB转TTL串口电路,但是CH340芯片上不能直接出来RS485电平信号,所以要通过电平转换芯片来实现。由于RS485一般用半双工通信,所以需要一个使能信号来控制RS485收发器的方向。从支持RS485的功能来讲CH340系列分为有TNOW引脚(如CH340B、CH340T和CH340E等)和无TNOW引脚(如CH340C/CH340K/CH340N等)两种。没有TNOW引脚的CH340实现RS485信号收发需要外加一个反相器,原理图如下:有TNOW引脚的CH340B可以省去反相

    2022年5月3日
    354
  • 关于在网页拼接时出现:“Uncaught SyntaxError: missing ) after argument list”的真凶在哪里

    关于在网页拼接时出现:“Uncaught SyntaxError: missing ) after argument list”的真凶在哪里

    2022年2月20日
    74
  • 51单片机驱动继电器模块点灯

    51单片机驱动继电器模块点灯51单片机驱动继电器模块点灯的使用ESP32与ESP8266简介ESP8266接口视图ESP32功能框图基于arduino的ESP32/ESP8266开发环境搭建基于arduino的ESP32/ESP8266开发环境烧录固件官方FLASH下载软件烧录固件总结

    2022年6月24日
    28
  • sigaction 函数

    sigaction 函数linux信号的使用,推荐用sigaction

    2022年5月26日
    44

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号