Bootstrap:カッコいいカレンダー『daterangepicker』の取扱いを調べた

Bootstrap:カッコいいカレンダー『daterangepicker』の取扱いを調べた

このプラグインの担当区分は日付の範囲指定です。
例えば、売上の期間集計とか『どこからどこの集計をするのか』を指示する事が出来ます。
ただし、標準状態ではPOSTの書き込みが無いので「どこに書けば良いの?」と苦戦してました。
と言う事で、個人的備忘録。

daterangepicker導入の経緯

Bootstrapのテンプレ Gentelella に標準搭載されてました。

で、売上とか来店数の集計にどうしても機関での変更と言うタスクが入るので活用してみようと。

Gentelellaでの該当箇所

static
├── build/
│  ├─── css/
│  ├─── js/
│  │ ├─── custom.js
│  │ ├─── custom.min.js
│  (以下略)
├── venders/
│  ├─── bootstrap-daterangepicker/
│  │ ├─── daterangepicker.css
│  │ ├─── daterangepicker.js
│  │ ├─── daterangepicker.scss
│  │ ├─── package.js
│  │ ├─── package.json
│  │ ├─── README.md
│  │ (以下略)
(以下略)

この中の【venders/bootstrap-daterangepicker/daterangepicker.js】がベースとなるJSファイル

で、カスタマイズしている項目は【build/js/custom.js ※またはcustom.min.js】に存在しました。

Gentelella カスタマイズ項目の該当箇所

/* DATERANGEPICKER */

function init_daterangepicker() {

    if (typeof($.fn.daterangepicker) === 'undefined') {
        return;
    }
    console.log('init_daterangepicker');

    var cb = function(start, end, label) {
        console.log(start.toISOString(), end.toISOString(), label);
        $('#reportrange span').html(start.format('MMMM D, YYYY') + ' - ' + end.format('MMMM D, YYYY'));
    };

    var optionSet1 = {
        startDate: moment().subtract(29, 'days'),
        endDate: moment(),
        minDate: '01/01/2012',
        maxDate: '12/31/2015',
        dateLimit: {
            days: 60
        },
        showDropdowns: true,
        showWeekNumbers: true,
        timePicker: false,
        timePickerIncrement: 1,
        timePicker12Hour: true,
        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')]
        },
        opens: 'left',
        buttonClasses: ['btn btn-default'],
        applyClass: 'btn-small btn-primary',
        cancelClass: 'btn-small',
        format: 'MM/DD/YYYY',
        separator: ' to ',
        locale: {
            applyLabel: 'Submit',
            cancelLabel: 'Clear',
            fromLabel: 'From',
            toLabel: 'To',
            customRangeLabel: 'Custom',
            daysOfWeek: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
            monthNames: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
            firstDay: 1
        }
    };

    $('#reportrange span').html(moment().subtract(29, 'days').format('MMMM D, YYYY') + ' - ' + moment().format('MMMM D, YYYY'));
    $('#reportrange').daterangepicker(optionSet1, cb);
    $('#reportrange').on('show.daterangepicker', function() {
        console.log("show event fired");
    });
    $('#reportrange').on('hide.daterangepicker', function() {
        console.log("hide event fired");
    });
    $('#reportrange').on('apply.daterangepicker', function(ev, picker) {
        console.log("apply event fired, start/end dates are " + picker.startDate.format('MMMM D, YYYY') + " to " + picker.endDate.format('MMMM D, YYYY'));
    });
    $('#reportrange').on('cancel.daterangepicker', function(ev, picker) {
        console.log("cancel event fired");
    });
    $('#options1').click(function() {
        $('#reportrange').data('daterangepicker').setOptions(optionSet1, cb);
    });
    $('#options2').click(function() {
        $('#reportrange').data('daterangepicker').setOptions(optionSet2, cb);
    });
    $('#destroy').click(function() {
        $('#reportrange').data('daterangepicker').remove();
    });

}

$(document).ready(function() {
    init_daterangepicker();
});

関連する箇所は他にも下の3つの要素があります。
これらはテンプレ内の使いどころによって分かれています。

  • init_daterangepicker_right();
  • init_daterangepicker_single_call();
  • init_daterangepicker_reservation();

期間指定の項目:10行目~13行目 & 54行目~55行目

10行目~13行目は下の画像の赤丸箇所になります。

ちなみに、今回は下の様に書き替えました。

#10~13行目
    var cb = function(start, end, label) {
        console.log(start.toISOString(), end.toISOString(), label);
        $('#reportrange span').html(start.format('YYYY/MM/DD') + ' - ' + end.format('YYYY/MM/DD'));
    };

#54~55行目
    $('#reportrange span').html('期間を設定してください');
    $('#reportrange').daterangepicker(optionSet1, cb);

12行目【$('#reportrange span').html(start.format('YYYY/MM/DD') + ' - ' + end.format('YYYY/MM/DD'));】
ここはピックアップした期間を赤丸の箇所に配置する際にどのような表示にするかを指示しています。YYYY/MM/DD で 2020/12/14と言う表記になります。

54行目は期間のピックアップが存在しない時に何を表示するかを指示しています。
【$('#reportrange span').html('期間を設定してください');】とした場合は画像の様に『期間を...』と言う文字を表示します。日付が入っていた方がカッコいいのですが、今回は諸事情で文字列にしました。

55行目は期間のピックアップが行われた時に何を表示するかを指示しています。
15行目から始まるoptionSet1で設定された値を10行目からのcb のルールに従って書いてねと言う意味です。

注意点

日付フォーマットについては長年のクセで最初 yyyy/mm/dd としてしまったのですが、これは間違いです。
JavaScript上では【mm = 分】なので表示されないか間違えた値が表示される事になります。
※ちなみにPHPでは【分 = i】になる。

15行目~52行目は表示オプション

    var optionSet1 = {
        startDate: moment().subtract(30, 'days'),
        endDate: moment().subtract(1, 'days'),
        minDate: '2012/01/01',
        maxDate: '2020/12/11',
        format: 'YYYY/MM/DD',
        dateLimit: {
            days: 60
        },
        alwaysShowCalendars: true,
        showDropdowns: true,
        showWeekNumbers: false,
        timePicker: false,
        timePickerIncrement: 1,
        timePicker12Hour: true,
        ranges: {
            /*'今日': [moment(), moment()],*/
            '昨日': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
            '最新7日間': [moment().subtract(7, 'days'), moment().subtract(1, 'days')],
            '最新30日間': [moment().subtract(30, 'days'), moment().subtract(1, 'days')],
            '今月': [moment().startOf('month'), moment().endOf('month')],
            '先月': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')]
        },
        opens: 'left',
        buttonClasses: ['btn btn-default'],
        applyClass: 'btn-small btn-primary',
        cancelClass: 'btn-small',
        separator: ' to ',
        locale: {
            applyLabel: '確定',
            cancelLabel: 'クリア',
            fromLabel: 'From',
            toLabel: 'To',
            customRangeLabel: 'カスタム',
            daysOfWeek: ['日', '月', '火', '水', '木', '金', '土'],
            monthNames: ['01月', '02月', '03月', '04月', '05月', '06月', '07月', '08月', '09月', '10月', '11月', '12月'],
            firstDay: 1
        }
    };

上が日本語化したもの。

今回の設置は店舗情報の分析なので、当日データは手に入らない=今日(Today)は廃止。
同様に抽出期間も最新で1日前なので【endDate: moment().subtract(1, 'days'),】としてmoment() から1日減算。
ついでに【startDate: moment().subtract(30, 'days'),】で初期値の開始日も変更。

あとはrenge とlocale を日本語化してやると使い勝手が良くなります。

54行目~76行目は動作を担当するパート

    $('#reportrange span').html('期間を設定してください');
    $('#reportrange').daterangepicker(optionSet1, cb);
    $('#reportrange').on('show.daterangepicker', function() {
        console.log("show event fired");
    });
    $('#reportrange').on('hide.daterangepicker', function() {
        console.log("hide event fired");
    });
    $('#reportrange').on('apply.daterangepicker', function(ev, picker) {
        let f = document.createElement('form');
            f.method = 'post';
            f.action = location.pathname;
            f.innerHTML = '<input type="text" name="fr" value='+  picker.startDate.format('YYYY/MM/DD') + '>' +
               '<input type="text" name="toe" value=' + picker.endDate.format('YYYY/MM/DD') + '>' +
               '<input type="submit" value="submit">';

            document.body.append(f);
        f.submit();
        console.log("apply event fired, start/end dates are " + picker.startDate.format('YYYY/MM/DD') + " to " + picker.endDate.format('YYYY/MM/DD'));
    });
    $('#reportrange').on('cancel.daterangepicker', function(ev, picker) {
        console.log("cancel event fired");
    });
    $('#options1').click(function() {
        $('#reportrange').data('daterangepicker').setOptions(optionSet1, cb);
    });
    $('#options2').click(function() {
        $('#reportrange').data('daterangepicker').setOptions(optionSet2, cb);
    });
    $('#destroy').click(function() {
        $('#reportrange').data('daterangepicker').remove();
    });

ここが悩んだパートです。
詳細まで書くと長くなりそうなのでそれは別記事で補填します。
この記事の解説では『どこがどの動作を担当しているか』に留めます。

  • 54行目:期間抽出が一切行われていない時に inptタグ で表示される内容。
  • 55行目:期間抽出が行われた時に inputタグ で表示される内容。
  • 56行目~58行目: id = reportrange が表示された時に動作するイベント。Ajaxで動かす場合の初期値POSTに使う。
  • 59行目~61行目:抽出用カレンダーが閉じる時に動作。ここに何か書く事はあまりないと思う。
  • 62行目~64行目:確定ボタンを押された時に動作するイベント。値の送信は基本的にココで行う事になるはず。
  • 68行目~73行目:カレンダーの日付クリックで動作する箇所。ここも基本的に書かなうと思う。
  • 74行目~76行目:クリアボタンを押した時に動作するイベント。値に初期値を送るなどすればOK。

サブボタンの【Yesterday/Last 7 Days】とかをクリックしても62行目~64行目がちゃんと動きます。
なので、それ専用の記載箇所は存在しないので気にしなくて大丈夫です。

補足解説:moment()

この関数は日付を取得します。moment()で本日の取得。
日付の減算には【subtract】加算には【add】を使います。

  • 1日前:moment().subtract(1, 'days')
  • 1か月前:moment().subtract(1, 'months')

まとめ

どうでもいい事だけど体系的には『【Bootstrap】かっこいいテンプレ Gentelella を見つけたので解析③』ってタイトルの方が良かったかなと。
でも『daterangepicker』ってGentelellaに使われてるだけじゃないから調べるにはこっちの方が良いのか。

まぁ何とか使いこなせそうで良かったです。

\ 最新情報をチェック /

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください