myesn

myEsn2E9

hi
github

DateRangePicker: 實現週/星期選擇器

說明#

image

期望:點擊某一天,自動選中這一天所在星期的開始和結束日期。

現狀:這是一個選擇時間範圍的需求,Date Range Picker 自身並沒有實現週選擇的功能,對於日期範圍,需要點一次開始,再點一次結束。

所以需要自己實現,步驟如下。

引入 week-picker.css#

.daterangepicker .calendar-table th,
.daterangepicker .calendar-table td { /* tighter */
    min-width: 20px !important;
}

.daterangepicker tr td.week { /* wider */
    width: 44px;
    color: #1a6cb3;
}

.daterangepicker tbody tr:hover {
    background-color: #f2f2f2;
}

.daterangepicker td.off {
    background-color: transparent !important;
}

    .daterangepicker td.off.in-range {
        /*background-color: #ebf4f8 !important;*/
        background-color: #e4eaec !important;
    }

    .daterangepicker td.off.start-date,
    .daterangepicker td.off.end-date {
        background-color: #5188b7 !important;
    }

.daterangepicker tbody tr.active td.week {
    color: #357ebd !important;
    background-color: #f2f2f2 !important;
    font-weight: bold;
}

.daterangepicker td.today,
.daterangepicker td.today.off {
    background-color: #ecf6f9 !important;
}

引入 week-picker.js#

/*
    代碼源自:https://jsfiddle.net/dj_floyd/f2hoygdw/

    使用方式:
    1. 引入 week-picker.css
    2. 引入 week-picker.js
    3. 頁面上添加一個 input 元素,設置 id 為 week-dp
    <input type="text" class="form-control datetimepicker-input" id="week-dp" data-toggle="datetimepicker" data-target="#week-dp">
    4. 在頁面的 js 文件中,調用 initWeekPicker 函數,傳入 '#week-dp' 作為參數

    獲取值:$('#week-dp').val()
*/

//moment.locale('ru') //depending on locale you can move start of week
/**
 * 初始化 周選擇器
 * 
 * 因為異步設置顯示的值,所以獲取值的方式變成了:
 * $(domSelector).data('weekStart');
 * $(domSelector).data('weekEnd');
 * @param {any} domSelector '#week-dp'
 * @param {any} format 默認 'YYYY-MM-DD'
 */
function initWeekPicker(domSelector, format) {
    const set_picker_start_end = (picker, when) => {
        //console.log('set_picker_start_end')
        let m = (when == 'now') ? moment() : moment(when); //moment

        let week_start = m.startOf('isoweek');
        let week_end = m.clone().endOf('isoweek');

        // 因為 setStartDate、setEndDate 之後會格式化顯示選擇的日期,
        // 但因為我們將 singleDatePicker設置為true,所以它在格式化的時候就不會帶上結束日期
        // 因此,這裡設置一個延遲,讓它在 setStartDate、setEndDate 之後設置值
        // 就是會出現一個閃爍的問題,不過影響不大,就當是動畫效果了
        setTimeout(() => {
            $(domSelector).val(week_start.format(format ?? 'YYYY-MM-DD') + ' ~ ' + week_end.format(format ??'YYYY-MM-DD'));
        }, 0);

        // 因為上面是延遲設置值,導致外部 initWeekPicker 之後,獲取 $(domSelector).val() 只有 week_start 的值(因為singleDatePicker設置為true,setEndDate不再生效)
        // 所以這裡將真正的值放在 data 中,頁面上異步顯示,外部獲取值的時候從 data 取,就不會出現調用 initWeekPicker 之後拿不到週範圍值的問題
        $(domSelector).data({
            weekStart: week_start.format(format ?? 'YYYY-MM-DD'),
            weekEnd: week_end.format(format ?? 'YYYY-MM-DD'),
        });

        //console.log(week_start.format('YYYY-MM-DD'), week_end.format('YYYY-MM-DD'));
        picker.setStartDate(week_start);
        picker.setEndDate(week_end);
    };

    $(domSelector).daterangepicker({
        "showDropdowns": true,
        "showISOWeekNumbers": false,
        "autoApply": true,
        "showCustomRangeLabel": false,
         //"startDate": '', //not work because of one calendar. will be set further
         //"endDate": '', //not work because of one calendar. will be set further
        "drops": "down",
        // daterangepicker 這個組件選日期範圍的需要點開始和結束兩次,為了實現點一次就選中一週的效果,設置為單選
        // 但這會導致一個問題,就是 /picker.setStartDate(week_start);picker.setEndDate(week_end); 之後,format 的格式只有week_start
        // 因為我們將 singleDatePicker設置為true,所以它在格式化的時候就不會帶上結束日期
        "singleDatePicker": true, //to make one click and one calendar
        "locale": {
            "format": "YYYY-MM-DD",
            //"weekLabel": "#",
        },
    });

    set_picker_start_end($(domSelector).data('daterangepicker'), 'now') //set current week selected

    $(domSelector).on('show.daterangepicker', function (ev, picker) {
        //console.log('show.daterangepicker', ev, picker);
        let active_cell = picker.container[0].querySelector('td.start-date');
        active_cell.parentElement.classList.add('active'); //tr goes active
    });

    // fix:解決 daterangepicker 顯示後,沒有點擊日期,點擊其他地方後,因為 autoApply:true,會自動關閉 picker,然後日期變成只有 startDate 的問題
    $(domSelector).on('hide.daterangepicker', function (ev, picker) {
        //console.log('hide.daterangepicker', ev, picker);

        set_picker_start_end(picker, picker.startDate);
    });

    $(domSelector).on('apply.daterangepicker', function (ev, picker) {
        //console.log('apply.daterangepicker', ev, picker);
        set_picker_start_end(picker, picker.startDate);
    });
}

使用方式#

html:

<input type="text" class="form-control datetimepicker-input" id="week-dp" data-toggle="datetimepicker" data-target="#week-dp">

js:

initWeekPicker('#week-dp');

參考#

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。