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') //ロケールに応じて週の開始を移動できます
/**
 * 初期化 周選択器
 * 
 * 非同期で表示される値を設定するため、値の取得方法が次のように変更されました:
 * $(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 は無効)
        // したがって、ここで実際の値をデータに格納し、ページ上で非同期に表示し、外部で値を取得する際にはデータから取得することで、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": '', //一つのカレンダーのため機能しません。後で設定されます
         //"endDate": '', //一つのカレンダーのため機能しません。後で設定されます
        "drops": "down",
        // daterangepicker コンポーネントは日付範囲を選択するために開始と終了を二度クリックする必要がありますが、一度のクリックで週を選択する効果を実現するために単一選択に設定します
        // しかし、これにより問題が発生します。picker.setStartDate(week_start);picker.setEndDate(week_end); の後、format の形式は week_start のみになります
        // singleDatePicker を true に設定しているため、フォーマット時に終了日が含まれません
        "singleDatePicker": true, //一度のクリックで一つのカレンダーを表示
        "locale": {
            "format": "YYYY-MM-DD",
            //"weekLabel": "#",
        },
    });

    set_picker_start_end($(domSelector).data('daterangepicker'), 'now') //現在の週を選択

    $(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 をアクティブにする
    });

    // 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');

参考#

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。