赞
踩
Date Range Picker是一个基于JQuery的时间选择器插件,提供了丰富的功能和优秀的界面,它的官网地址http://www.daterangepicker.com
但是这个插件有一个比较坑比的是没有月选择器,只有日期和时间选择器,项目中用到了日期选择器的功能,但是在这个项目的另外一个业务又要需要月选择器,如果重新引入一个日期选择器又多了引入文件,如果重写一个功能又不划算,于是决定直接在daterangepicker这个插件上增加月范围选择器,也要保证不影响它原来功能,也不需要引入其他的框架。
因此,使用该扩展出的月份选择器前提是会使用daterangepicker本身的功能。
首先要引入datarangepicker的需要的文件
- <script type="text/javascript" src="https://cdn.jsdelivr.net/jquery/latest/jquery.min.js"></script>
- <script type="text/javascript" src="https://cdn.jsdelivr.net/momentjs/latest/moment.min.js"></script>
- <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.min.js"></script>
- <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.css" />
css文件:
- *{
- margin: 0;
- padding: 0;
- }
- .daterangepicker .drp-buttons {
- text-align: left;
- }
- .daterangepicker .drp-selected {
- display: none;
- }
- div.drp-calendar.left {
- margin-right: 20px!important;
- }
- li{
- list-style: none;
- }
- .s-cal {
- width: 150px;
- margin-top: 8px;
- }
-
- div.calendar.left {
- margin-right: 20px!important;
- }
-
- .s-calTitle>span {
- padding-left: 5px;
- padding-right: 5px;
- color: #08c;
- cursor: pointer;
-
- line-height: 25px;
- border-radius: 3px;
- }
- .s-calTitle>span:hover {
- background-color: #08c;
- color: #fff;
- }
- .s-calTitle>p {
- line-height: 25px;
- margin-bottom: 2px;
- }
- .s-calTitle,
- .s-calMonth {
- display: flex;
- justify-content: space-between;
- margin-bottom: 10px;
- }
- ul.s-calMonth>li {
- cursor: pointer;
- padding: 5px;
- border-radius: 3px;
- }
- ul.s-calMonth>li:hover{
- background-color: #EBF4FB;
- }
- ul.s-calMonth>li.onFocus {
- background-color: #08c;
- color: #fff;
- }
- ul.s-calMonth>li.disabled {
- cursor: not-allowed;
- pointer-events: none;
- opacity: 0.6;
- }
- .s-calViewTitle {
- text-align: center;
- padding-top: 3px;
- padding-bottom: 3px;
- background-color: #f5f5f5;
- border-radius: 3px;
- font-weight: bold;
- color: #08c;
- }

注:css文件的.daterangepicker .drp-buttons,.daterangepicker .drp-selected,div.drp-calendar.left是直接覆盖daterangepicker的css样式,由于引入的框架版本不同可能会产生不同的效果,可能需要对这三个样式酌情修改,但是不影响使用。
扩展代码:
- /**
- * 基于Date Range Picker的月份选择器扩展
- * github:https://github.com/RidingACodeToStray/daterangepicker-monthrangepicker
- * @param {起始时间} s
- * @param {终止时间} e
- * @param {最外层的div对象} classDom
- * @param {内层的span对象} idDom
- * @param {显示时间格式} sformat
- * @param {是否显示日历} showCalendars
- * @param {配置默认可选的时间范围} ranges
- * @param {是否展示自定义范围} scrl
- * @param {是否使用月份选择器} monthRange
- */
- var datePicker = function(s, e, classDom, idDom, sformat = 'YYYY-MM-DD', showCalendars = true, ranges, scrl = true,monthRange) {
- if (!ranges) {
- ranges = {
- 'Today': [moment(), moment()],
- 'Yesterday': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
- 'Last 7 Days': [moment().subtract(6, 'days'), moment()],
- 'Last 30 Days': [moment().subtract(29, 'days'), moment()],
- 'This Month': [moment().startOf('month'), moment().endOf('month')],
- 'Last Month': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')]
- }
- }
- var start = s || moment();
- var end = e || moment();
-
- function cb(start, end) {
- classDom.html(start.format(sformat) + " - " + end.format(sformat));
- }
- idDom.daterangepicker({
- locale: {
- format: sformat
- },
- alwaysShowCalendars: showCalendars,
- showDropdowns: true,
- startDate: start,
- showCustomRangeLabel: scrl,
- endDate: end,
- opens: "right",
- ranges: ranges
- },
- cb
- );
- cb(start, end);
- if(monthRange){
- //修改日期选择器
- $('div.drp-calendar').empty().html('<div class="s-cal"><div class="s-calTitle"><span class="glyphicon glyphicon-arrow-left s-calLastYear"aria-hidden="true"></span><p>2018</p><span class="glyphicon glyphicon-arrow-right s-calNextYear"aria-hidden="true"></span></div><ul class="s-calMonth"><li data-month="01">Jan</li><li data-month="02">Feb</li><li data-month="03">Mar</li><li data-month="04">Apr</li></ul><ul class="s-calMonth"><li data-month="05">May</li><li data-month="06">Jun</li><li data-month="07">Jul</li><li data-month="08">Aug</li></ul><ul class="s-calMonth"><li data-month="09">Sep</li><li data-month="10">Oct</li><li data-month="11">Nov</li><li data-month="12">Dec</li></ul></div>');
- $('div.drp-calendar.left > .s-cal').before('<div class="s-calViewTitle">Start Date</div>');
- $('div.drp-calendar.right > .s-cal').before('<div class="s-calViewTitle">End Date</div>');
- var timePickerDom = $('.s-timePicker'),
- sYearView = $($('.s-calTitle > p')[0]),
- eYearView = $($('.s-calTitle > p')[1]),
- monthViewLis = $('.s-calMonth > li'),
- sMonthViewLis = $($('.s-cal')[0]).find('.s-calMonth > li'),
- eMonthViewLis = $($('.s-cal')[1]).find('.s-calMonth > li'),
- tabs = $('div.daterangepicker > div.ranges > ul > li'),
- lastTab = $('div.daterangepicker > div.ranges > ul > li:last-child');
- //缓存日期
- var tempSYear,
- tempEyear,
- tempSMonth,
- tempEMonth;
- //变换日历视图修改样式
- function changeView(isAngle = false){
- var currentSYear = sYearView.text();
- var currentEYear = eYearView.text();
- eMonthViewLis.removeClass('disabled');
- if(isAngle){
- //年份不一致判断
- if(currentSYear > currentEYear){
- eMonthViewLis.addClass('disabled');
- }
- if(currentSYear < currentEYear){
- eMonthViewLis.removeClass('disabled');
- }
- if(currentSYear == tempSYear){
- sMonthViewLis.eq(tempSMonth).addClass('onFocus');
- }
- if(currentEYear == tempEyear){
- eMonthViewLis.eq(tempEMonth).addClass('onFocus');
- }
- }else{
- if(tempSMonth > tempEMonth){
- //如果选中起始月份较大,则将日期赋值为起始月份
- eMonthViewLis.removeClass('onFocus');
- eMonthViewLis.eq(tempSMonth).addClass('onFocus');
- putRangeDate();
- }
- eMonthViewLis.each(function(index){
- if((index) == Number(tempSMonth)){
- return false;
- }
- $(this).addClass('disabled');
- })
- }
- }
- //生成日期
- function putRangeDate(){
- var sYearDate = $($('.s-cal')[0]).find('.s-calTitle > p').text();
- var sMonthDate = $($('.s-cal')[0]).find('.s-calMonth > li.onFocus').data('month');
- var eYearDate = $($('.s-cal')[1]).find('.s-calTitle > p').text();
- var eMonthDate = $($('.s-cal')[1]).find('.s-calMonth > li.onFocus').data('month');
- tempSYear = sYearDate;
- tempEyear = eYearDate;
- tempSMonth = Number(sMonthDate) - 1;
- tempEMonth = Number(eMonthDate) - 1;
- timePickerDom.text(sYearDate+'-'+sMonthDate+' - '+eYearDate+'-'+eMonthDate);
- changeView();
- }
- //给View赋值样式
- function putDateView(sy,ey,sm,em){
- sy && sYearView.text(sy);//赋值起始年份
- ey && eYearView.text(ey);//赋值终止年份
- sm && sMonthViewLis.eq(sm).addClass('onFocus');//高亮起始月份
- em && eMonthViewLis.eq(em).addClass('onFocus'); //高亮终止月份
- }
- //取日期给View赋值样式
- function getRangeDate(){
- var datePeriod = timePickerDom.text().split(' - ');
- var sDate = datePeriod[0].split('-'); //起始年月
- var eDate = datePeriod[1].split('-'); //终止年月
- tempSYear = sDate[0];
- tempEyear = eDate[0];
- tempSMonth = Number(sDate[1]) - 1;
- tempEMonth = Number(eDate[1]) - 1;
- putDateView(tempSYear,tempEyear,tempSMonth,tempEMonth);
- }
- getRangeDate();
- changeView();
- //前一年
- $('.s-calLastYear').click(function(e){
- var startDateDom = $(e.target).next('p');
- startDateDom.text(Number(startDateDom.text()) - 1);
- $(this).parents('.s-cal').find('.s-calMonth > li').removeClass('onFocus');
- changeView(true);
- })
- //后一年
- $('.s-calNextYear').click(function(e){
- var startDateDom = $(e.target).prev('p');
- startDateDom.text(Number(startDateDom.text()) + 1);
- $(this).parents('.s-cal').find('.s-calMonth > li').removeClass('onFocus');
- changeView(true);
- })
- //选中月份
- monthViewLis.click(function(){
- tabs.removeClass('active');
- lastTab.addClass('active');
- //两个if处理使用箭头移动导致都没有选中月份的情况
- if(!sMonthViewLis.hasClass('onFocus')){
- sMonthViewLis.eq(0).addClass('onFocus');
- }
- if(!eMonthViewLis.hasClass('onFocus')){
- eMonthViewLis.eq(0).addClass('onFocus');
- }
- $(this).parents('.s-cal').find('.s-calMonth > li').removeClass('onFocus');
- $(this).addClass('onFocus');
- putRangeDate();
- })
-
- }
- };

如何使用:
- <div id="s-timeRange" class="pull-right s-timeRange">
- <i class="glyphicon glyphicon-calendar fa fa-calendar"></i>
- <span class="s-timePicker"></span> <b class="caret"></b>
- </div>
- <script>
- $(function() {
- var timeRangeDom = $('#s-timeRange'),
- timePickerDom = $('.s-timePicker');
- datePickers(
- moment().subtract(1, 'month').startOf('month'),
- moment().subtract(1, 'month').endOf('month'),
- timePickerDom,
- timeRangeDom,
- 'YYYY-MM',
- true,
- {
- 'This Month': [moment().startOf('month'), moment().endOf('month')],
- 'Last Month': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')],
- 'Last Three Months':[moment().subtract(3, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')],
- 'Last Year':[moment().subtract(12, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')]
- },
- true,
- true
- );
- });
- </script>

展现出的效果(结合bootstrap使用的项目截图):
从以上代码可以看出,这种扩展实际上是将调用daterangepicker插件功能的方法封装在一个自定义方法datePickers中,其他方法提供了各种自定义选择器模块的方法,另外该方法也提供了一个参数monthRange,若传入为false,则默认调用为时间日期选择器,如何选择参数可以根据daterangepicker官方提供的文档来配置,如果传入monthRange为true,则将当前选择器设置为月范围选择器。
参数说明:
s:默认展示起始时间,静态可以自定义字符串格式,动态的可以调用moment()方法生成;
e:默认展示结束时间,静态可以自定义字符串格式,动态的可以调用moment()方法生成;
classDom:选择最外层div的jquery对象;
idDom:选择的内层的span的jquery对象;
sformat:展示时间格式,请参见Date Range Picker文档;
showCalendars:是否默认显示日历,即点击日期下拉就展开日历,默认true;
ranges:自定义下拉的日期选项,对象格式,键名为展示内容,键值为数组两个元素,分别表示起始和结束时间,详情参见参见Date Range Picker文档;
scrl:是否展示自定义日期按钮,若需要自定义日期或者使用月份范围选择器功能则需要设置为true;
monthRange:是否使用月份范围选择器功能
另外也可以将datePicker写到一个js文件中结合相关的css文件单独引入,在调用如何使用部分的js代码引用
- <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.css" />
- <link rel="stylesheet" href="./daterangepicker.monthpicker.css">
- <script type="text/javascript" src="https://cdn.jsdelivr.net/jquery/latest/jquery.min.js"></script>
- <script type="text/javascript" src="https://cdn.jsdelivr.net/momentjs/latest/moment.min.js"></script>
- <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.min.js"></script>
- <script src="./daterangepicker.monthpicker.js"></script>
github地址:https://github.com/RidingACodeToStray/daterangepicker-monthrangepicker
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。