bootstrap中daterangepicker组件的使用(二)

为了实现 bootstrap中daterangepicker组件的使用(一) 中的需求,我对demo进行了定制,具体需求可以参见:bootstrap中daterangepicker组件的使用(一) : https://blog.csdn.net/liuying1802028915/article/details/84401953

此demo的作用是根据两个变量动态算出默认的开始日期和结束日期,也就是说在日期控件打开的时候,默认的开始日期和结束日期都会默认的在日期控件中选中,并且他们中间的日期也会选中.如下图所示:

接下来直接粘代码了:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script>
        var customTimePeriodType = "1"; //customTimePeriodType表示 选的是7天 1个月还是2个月   1代表7天 2代表1个月 3代表2个月 customTimePeriodType影响的是日期范围的长度
        var customTimeGranularity = "1";  //customTimeGranularity 选的是哪个事件粒度  日 周还是月  1代表日 2代表周 3代表月 customTimeGranularity影响的是最后一天从那天算起
        var defaultStartDate = null;
    </script>
    <title>在选择事件范围时,选择一个日期根据选择的左面还是右面,进行自动匹配开始日期和结束日期</title>
    <link rel="stylesheet" href="css/bootstrap.min.css">
    <link rel="stylesheet" href="css/daterangepicker.css">
    <script src="js/jquery-2.2.3.min.js"></script>
    <script src="js/moment.js"></script>
    <script src="js/daterangepicker.js"></script>
    <script type="text/javascript">

        $(function () {

            defaultStartDate = getPageStartDate();

            //单个时间插件
           $("input[name='date1']").daterangepicker(
                {
                    singleDatePicker: true,//设置为单个的datepicker,而不是有区间的datepicker 默认false
                    showDropdowns: true,//当设置值为true的时候,允许年份和月份通过下拉框的形式选择 默认false
                    autoUpdateInput: false,//1.当设置为false的时候,不给与默认值(当前时间)2.选择时间时,失去鼠标焦点,不会给与默认值 默认true
                    timePicker24Hour : true,//设置小时为24小时制 默认false
                    timePicker : false,//可选中时分 默认false
                    locale: {
                        format: "YYYY-MM-DD",
                        separator: " - ",
                        daysOfWeek: ["日","一","二","三","四","五","六"],
                        monthNames: ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"]
                    }

                }
            ).on('cancel.daterangepicker', function(ev, picker) {
                $("#date1").val("请选择日期");
                $("#submitDate").val("");
            }).on('apply.daterangepicker', function(ev, picker) {
                $("#submitDate").val(picker.startDate.format('YYYY-MM-DD'));
                $("#date1").val(picker.startDate.format('YYYY-MM-DD'));
            });

            //区间时间插件
            $("input[name='date2']").daterangepicker(
                {
                    autoUpdateInput: false,
                    startDate: getPageStartDate(),
                    endDate: getPageEndDate(),
                    maxDate: getPageMaxDate(),
                    locale: {
                        format: "YYYY-MM-DD",
                        separator: " - ",
                        applyLabel: "确认",
                        cancelLabel: "清空",
                        fromLabel: "开始时间",
                        toLabel: "结束时间",
                        customRangeLabel: "自定义",
                        daysOfWeek: ["日","一","二","三","四","五","六"],
                        monthNames: ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],
                    }
                }
            ).on('cancel.daterangepicker', function(ev, picker) {
                $("#date2").val("请选择日期范围");
                $("#startTime").val("");
                $("#endTime").val("");
            }).on('apply.daterangepicker', function(ev, picker) {
                $("#startTime").val(picker.startDate.format('YYYY-MM-DD'));
                $("#endTime").val(picker.endDate.format('YYYY-MM-DD'));
                $("#date2").val(picker.startDate.format('YYYY-MM-DD')+" 至 "+picker.endDate.format('YYYY-MM-DD'));
            });

        });

        //获取日期控件上最大可选的一天
        function getPageMaxDate(){
            //moment() 表示今天
            var _maxDate = moment().subtract(1, 'days');//最大可选的日期默认是今天的前一天
            if(customTimeGranularity == 1){
                _maxDate = moment().subtract(1, 'days');//最大可选的日期是今天的前一天
            }else if(customTimeGranularity == 2){
                _maxDate = moment().subtract(8, 'days');//最大可选的日期是今天的前8天
            }else if(customTimeGranularity == 3){
                _maxDate = moment().subtract(31, 'days');//最大可选的日期是今天的前31天
            }
            return _maxDate;
        }

        //根据customTimePeriodType 和 customTimeGranularity 参数 获取默认选中的开始日期
        function getPageStartDate(){
            var _date = moment().subtract(8, 'days');
            if(customTimePeriodType == 1){//日期长度 为 7天
                if(customTimeGranularity == 1){//时间粒度 为 日
                    _date = moment().subtract(8, 'days');
                }else if(customTimeGranularity == 2){//时间粒度 为 周
                    _date = moment().subtract(15, 'days');
                }else if(customTimeGranularity == 3){//时间粒度 为 月
                    _date = moment().subtract(39, 'days');
                }
            }else if(customTimePeriodType == 2){//日期长度 为 1个月
                if(customTimeGranularity == 1){//时间粒度 为 日
                    _date = moment().subtract(31, 'days');
                }else if(customTimeGranularity == 2){//时间粒度 为 周
                    _date = moment().subtract(39, 'days');
                }else if(customTimeGranularity == 3){//时间粒度 为 月
                    _date = moment().subtract(61, 'days');
                }
            }else if(customTimePeriodType == 3){//日期长度 为 2个月
                if(customTimeGranularity == 1){//时间粒度 为 日
                    _date = moment().subtract(61, 'days');
                }else if(customTimeGranularity == 2){//时间粒度 为 周
                    _date = moment().subtract(69, 'days');
                }else if(customTimeGranularity == 3){//时间粒度 为 月
                    _date = moment().subtract(91, 'days');
                }
            }
            var _date1 = new Date(_date);
            return _date1;
        }

        //根据customTimePeriodType 和 customTimeGranularity 参数 获取默认选中的结束日期
        function getPageEndDate(){
            var _date = moment().subtract(1, 'days');
            if(customTimePeriodType == 1){//日期长度 为 7天
                if(customTimeGranularity == 1){//时间粒度 为 日
                    _date = moment().subtract(1, 'days');
                }else if(customTimeGranularity == 2){//时间粒度 为 周
                    _date = moment().subtract(8, 'days');
                }else if(customTimeGranularity == 3){//时间粒度 为 月
                    _date = moment().subtract(31, 'days');
                }
            }else if(customTimePeriodType == 2){//日期长度 为 1个月
                if(customTimeGranularity == 1){//时间粒度 为 日
                    _date = moment().subtract(1, 'days');
                }else if(customTimeGranularity == 2){//时间粒度 为 周
                    _date = moment().subtract(8, 'days');
                }else if(customTimeGranularity == 3){//时间粒度 为 月
                    _date = moment().subtract(31, 'days');
                }
            }else if(customTimePeriodType == 3){//日期长度 为 2个月
                if(customTimeGranularity == 1){//时间粒度 为 日
                    _date = moment().subtract(1, 'days');
                }else if(customTimeGranularity == 2){//时间粒度 为 周
                    _date = moment().subtract(8, 'days');
                }else if(customTimeGranularity == 3){//时间粒度 为 月
                    _date = moment().subtract(31, 'days');
                }
            }
            var _date2 = new Date(_date);
            return _date2;
        }

        function getFormatDay(dateTemp){
            var date11 = new Date(dateTemp);
            var seperator = "-";
            var year = date11.getFullYear();
            var month = date11.getMonth()+1;
            var day = date11.getDate();
            if(month >= 1 && month <= 9){
                month = "0"+month;
            }
            if(day >= 1 && day <= 9){
                day = "0"+day;
            }
            var currentDay = year + seperator + month + seperator + day;
            return currentDay;
        }
    </script>
</head>
<body>
    <div>
        我是一个DateRangePicker的小练习
    </div>
    <div class="form-group">
        <label>单个</label>
        <div>
            <input type="text" name="date1" id="date1" class="form-control" style="width: 20%;">
            <input type="hidden" id = "submitDate" name="submitDate" class="form-control" />
        </div>
    </div>

    <div class="form-group">
        <label>区间</label>
        <div>
            <input type="text" name="date2" id="date2" class="form-control" style="width: 20%;">
            <input type="hidden" id = "startTime" name="startTime" class="form-control" />
            <input type="hidden" id = "endTime" name="endTime" class="form-control" />
        </div>
    </div>
</body>
</html>

如上代码所示,打开区间的日期控件的代码是:

//区间时间插件
            $("input[name='date2']").daterangepicker(
                {
                    autoUpdateInput: false,
                    startDate: getPageStartDate(),
                    endDate: getPageEndDate(),
                    maxDate: getPageMaxDate(),
                    locale: {
                        format: "YYYY-MM-DD",
                        separator: " - ",
                        applyLabel: "确认",
                        cancelLabel: "清空",
                        fromLabel: "开始时间",
                        toLabel: "结束时间",
                        customRangeLabel: "自定义",
                        daysOfWeek: ["日","一","二","三","四","五","六"],
                        monthNames: ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],
                    }
                }
            ).on('cancel.daterangepicker', function(ev, picker) {
                $("#date2").val("请选择日期范围");
                $("#startTime").val("");
                $("#endTime").val("");
            }).on('apply.daterangepicker', function(ev, picker) {
                $("#startTime").val(picker.startDate.format('YYYY-MM-DD'));
                $("#endTime").val(picker.endDate.format('YYYY-MM-DD'));
                $("#date2").val(picker.startDate.format('YYYY-MM-DD')+" 至 "+picker.endDate.format('YYYY-MM-DD'));
            });

其中

startDate参数 可以使用一个函数获得:getPageStartDate()

同理:

endDate参数 可以使用一个函数获得:getPageEndDate()
maxDate参数 可以使用一个函数获得:getPageMaxDate()

其中:

function getPageStartDate(){
            var _date = moment().subtract(8, 'days');
            if(customTimePeriodType == 1){//日期长度 为 7天
                if(customTimeGranularity == 1){//时间粒度 为 日
                    _date = moment().subtract(8, 'days');
                }else if(customTimeGranularity == 2){//时间粒度 为 周
                    _date = moment().subtract(15, 'days');
                }else if(customTimeGranularity == 3){//时间粒度 为 月
                    _date = moment().subtract(39, 'days');
                }
            }else if(customTimePeriodType == 2){//日期长度 为 1个月
                if(customTimeGranularity == 1){//时间粒度 为 日
                    _date = moment().subtract(31, 'days');
                }else if(customTimeGranularity == 2){//时间粒度 为 周
                    _date = moment().subtract(39, 'days');
                }else if(customTimeGranularity == 3){//时间粒度 为 月
                    _date = moment().subtract(61, 'days');
                }
            }else if(customTimePeriodType == 3){//日期长度 为 2个月
                if(customTimeGranularity == 1){//时间粒度 为 日
                    _date = moment().subtract(61, 'days');
                }else if(customTimeGranularity == 2){//时间粒度 为 周
                    _date = moment().subtract(69, 'days');
                }else if(customTimeGranularity == 3){//时间粒度 为 月
                    _date = moment().subtract(91, 'days');
                }
            }
            var _date1 = new Date(_date);
            return _date1;
        }

其中 默认的开始日期是根据 customTimePeriodType 和 customTimeGranularity 这两个参数算出来的,其中又用到了 

moment().subtract(8, 'days'); 函数 这两个函数是 moment.js 中的函数,也是封装好的直接可以使用,具体细节这里就不多说了,需要看源码,或者官网的demo

至于getPageEndDate() 函数 和 getPageMaxDate() 我就不细说了,同 getPageStartDate() 一样.

二.并且这个demo中海油一个功能是:

根据点击选择的日期自动算出剩下的日期(开始日期或结束日期)

什么意思呢,让我给你细细道来,首先 看到了上图的日期控件 有两个月份,默认有一个事件范围,这个时间范围是7天, 开始日期是2018-10-12 结束日期是2018-10-19 那么我点击左侧日历中的一个日期,就把点击的日期作为开始日期,长度7天来算出结束日期,也就是说,假如我点击了3号,如下所示:

自己算出了结束日期是2018-10-10,那么我点击的是右侧日历也就是说11月份的某个日期呢,比如我点击了2018-11-15 ,如下所示:

他会将点击选择的2018-11-15这一天作为结束日期,以7天为长度算出开始日期是2018-11-08 并且显示在日期控件上,这个需求蛋疼吧,我刚开始拿到的时候也是一脸懵逼,不知道怎么做,显示印了一个laydate的组件,demo很简单,但是蛋疼的是他的源码没开放,源码是压缩过后的,我是没有找到未压缩版的源码,不能进行修改,所以没法实现这样的所能,所幸的是我找到了bootstrap中daterangepicker这个组件,他的源码是开源的,可以进行修改,接下来我就把修改过后的源码粘过来供大家参考.

主要进行修改的源码部分是 

clickDate() 函数,也就是说组件中点击一个日期的函数,在这个函数中,通过点击的日期算出算出剩下的开始日期或者结束日期,在通过这个组件的setStartDate() 函数 和 setEndDate() 函数即可进行定制.倒也不是很难,接下来我就把代码放上来:
clickDate: function(e) {

            if (!$(e.target).hasClass('available')) return;

            // debugger;
            var sss = customTimePeriodType;
            var title = $(e.target).attr('data-title');
            var row = title.substr(1, 1);
            var col = title.substr(3, 1);
            var cal = $(e.target).parents('.calendar');
            var date = cal.hasClass('left') ? this.leftCalendar.calendar[row][col] : this.rightCalendar.calendar[row][col];
            // var dateTemp = cal.hasClass('left') ? this.leftCalendar.calendar[row][col] : this.rightCalendar.calendar[row][col];  //当时这样写,后面对dateTemp对象 subtract处理后,date的值也会跟着变化 所以得克隆一下,也就是下一句
            var dateTemp = date.clone();//clone()后 对dateTemp 对象进行 subtrace处理后 date 不会变 满足我的需求


            //根据需求,下面是对daterangepicker控件的修改
            var clickLeftOrRight = "left";//clickLeftOrRight 参数表示点击的日期是日期左边控件的还是右边控件的 默认是左边
            if(cal.hasClass('left')){
                clickLeftOrRight = "left";
            }
            if(cal.hasClass('right')){
                clickLeftOrRight = "right";
            }

            var _startDay = defaultStartDate;
            var dateTemp2 = date.clone();
            var startDay = new Date(_startDay);
            var clickDay = new Date(dateTemp2);
            var flag = false;
            var _timePeriod = -7;
            if(clickLeftOrRight == "left"){//clickLeftOrRight 如果为left 表示点击的是左边的日期 那么点击的日期就是开始日期 往后推算结束日期
                if(customTimePeriodType == 1){
                    _timePeriod = -7;
                }else if(customTimePeriodType == 2){
                    _timePeriod = -30;
                }else if(customTimePeriodType == 3){
                    _timePeriod = -60;
                }
            }else if(clickLeftOrRight == "right"){//clickLeftOrRight 如果为righth 表示点击的是右边的日期 那么点击的日期就是结束日期 往前推算开始日期
                if(customTimePeriodType == 1){
                    _timePeriod = 7;
                }else if(customTimePeriodType == 2){
                    _timePeriod = 30;
                }else if(customTimePeriodType == 3){
                    _timePeriod = 60;
                }
            }else{
                return;
            }

            var afterTimePeriodDate = null; //afterTimePeriodDate 为 根据点击的日期推算的日期
            var startRelateEnd = false;//默认是结束时间大于开始时间,如果结束时间小于开始时间 则将startRelateEnd 参数置为true
            if(clickLeftOrRight == "left"){
                if(clickDay.getTime() > startDay.getTime()){
                    alert("所选日期不能小于默认范围的开始日期");
                    return;
                }else{
                    afterTimePeriodDate = dateTemp.subtract(_timePeriod, 'days');
                    var endDay = new Date(afterTimePeriodDate);
                    if(clickDay && endDay && clickDay.getTime() > endDay.getTime()){
                        startRelateEnd = true;
                    }
                    flag = true;
                }
            }else if(clickLeftOrRight == "right"){
                afterTimePeriodDate = dateTemp.subtract(_timePeriod, 'days');
                var endDay = new Date(afterTimePeriodDate);
                if(clickDay && endDay && clickDay.getTime() > endDay.getTime()){
                    startRelateEnd = true;
                }
                flag = true;
            }else{
                return;
            }



            //
            // this function needs to do a few things:
            // * alternate between selecting a start and end date for the range,
            // * if the time picker is enabled, apply the hour/minute/second from the select boxes to the clicked date
            // * if autoapply is enabled, and an end date was chosen, apply the selection
            // * if single date picker mode, and time picker isn't enabled, apply the selection immediately
            //

            if (this.endDate || date.isBefore(this.startDate, 'day')) {
                if (this.timePicker) {
                    var hour = parseInt(this.container.find('.left .hourselect').val(), 10);
                    if (!this.timePicker24Hour) {
                        var ampm = this.container.find('.left .ampmselect').val();
                        if (ampm === 'PM' && hour < 12)
                            hour += 12;
                        if (ampm === 'AM' && hour === 12)
                            hour = 0;
                    }
                    var minute = parseInt(this.container.find('.left .minuteselect').val(), 10);
                    var second = this.timePickerSeconds ? parseInt(this.container.find('.left .secondselect').val(), 10) : 0;
                    date = date.clone().hour(hour).minute(minute).second(second);
                }
                // this.endDate = null;
                if(!startRelateEnd){//startRelateEnd 为true时 表示结束时间 小于 开始时间 startRelateEnd为false时表示结束时间大于开始时间
                    this.setStartDate(date.clone());
                    if(flag){
                        this.setEndDate(afterTimePeriodDate.clone());
                    }
                }else{
                    this.setStartDate(afterTimePeriodDate.clone());
                    if(flag){
                        this.setEndDate(date.clone());
                    }
                }

            } else if (!this.endDate && date.isBefore(this.startDate)) {
                //special case: clicking the same date for start/end, 
                //but the time of the end date is before the start date
                this.setEndDate(this.startDate.clone());
            } else {
                if (this.timePicker) {
                    var hour = parseInt(this.container.find('.right .hourselect').val(), 10);
                    if (!this.timePicker24Hour) {
                        var ampm = this.container.find('.right .ampmselect').val();
                        if (ampm === 'PM' && hour < 12)
                            hour += 12;
                        if (ampm === 'AM' && hour === 12)
                            hour = 0;
                    }
                    var minute = parseInt(this.container.find('.right .minuteselect').val(), 10);
                    var second = this.timePickerSeconds ? parseInt(this.container.find('.right .secondselect').val(), 10) : 0;
                    date = date.clone().hour(hour).minute(minute).second(second);
                }
                this.setEndDate(date.clone());
                if (this.autoApply) {
                  this.calculateChosenLabel();
                  this.clickApply();
                }
            }

            if (this.singleDatePicker) {
                this.setEndDate(this.startDate);
                if (!this.timePicker)
                    this.clickApply();
            }

            this.updateView();

        },

其中都有注释,我这里就不多说了,稍后我会把整个的源码放到github上

 

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值