bootstrap-datepickerで期間を指定する場合のカスタマイズ

Shunsuke Sawada

Twitter Bootstrap使ってるとどうもjQuery UIのカレンダーのデザインが気に食わなくて、bootstrap-datepickerを使う人が多い気がします。jQuery UIは機能が凄いからいいけどね。

で、データピッカーなんですが、ちょっとソースがいろいろあって混乱してしまうので整理します。

Stefan Petre
http://www.eyecon.ro/bootstrap-datepicker/

 ↓

vitalets
https://github.com/vitalets/bootstrap-datepicker

 ↓

eternicode
https://github.com/eternicode/bootstrap-datepicker

多分こんな流れです。
eternicodeのオンラインデモは分かりやすくていい。

期間を指定させる

単一の日付けではなくて、○月○日〜○月○日といった感じ。
やり方はいろいろあるだろうけど、こんな感じで。


• From:とTo:のテキストフィールドを2つ。

• カレンダーを選択することでしか入力を受け付けない。

From:で日付を選択したら、自動的にTo:のカレンダーが表示される。

To:ではFrom:で選択された日付以前は選択できないようにする。

• Date pickerのバグをCSSでカバーする。

まずは見た目。

データピッカー

readonlyをつけて、タイピングによる入力はうけつけません。
  

html
1
input name="" id="day-start" readonly="readonly" type="text"

こんな感じでデータピッカーを有効に。

bootstrap datepicker

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$(function(){
    $('.datepicker1').datepicker({
        //オプション
        todayHighlight : false,
        autoclose : true,
        keyboardNavigation : false
    });

    $('.datepicker2').datepicker({
        //オプション
        todayHighlight : false,
        autoclose : true,
        keyboardNavigation : false
    });
});

各種メソッドの使用と、おまけの機能

From:の日付が変更されたら(changeDate)、To:のカレンダーを表示(show)してます。
.on('changeDate', function(e){
$('.datepicker2').datepicker('show');

その日付以前を無効化するには、setStartDateメソッドです。
$('.datepicker2').datepicker('setStartDate', sd);

ついでなので、From:の○日前から選択不可にするという機能もつけてみた。
From:の○日後でも大丈夫です。
sd = computeDate(yyyy, mm, dd, 0);
の 0 に数字を入れると1日後とか1日前とか設定できる。
ここではFrom:で選んだ日からTo:でも選択できるようにするので0のままで。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$(function(){
    $('.datepicker1').datepicker() 
        .on('changeDate', function(e){ //開始日が選択されたら
            $('.datepicker2').datepicker('show'); //終了日のカレンダーを表示
            selected_date = e['date']; //開始日のデータ取得
            yyyy = selected_date.getFullYear();
            mm = selected_date.getMonth() + 1;
            dd = selected_date.getDate();
            sd = computeDate(yyyy, mm, dd, 0); //0000-00-00の形で指定日後が返ってくる
            $('.datepicker2').datepicker('setStartDate', sd); //start日より前の日を無効化する
    });
});

function computeDate(year, month, day, addDays) {
    var dt = new Date(year, month - 1, day);
    var baseSec = dt.getTime();
    var addSec = addDays * 86400000;//日数 * 1日のミリ秒数
    var targetSec = baseSec + addSec;
    dt.setTime(targetSec);
    return dt;
}

バグに対応

日付ではなく期間を指定させるので、特定の日がハイライトされているとユーザーを混乱させてしまうかもしれません。
オプションで todayHighlight:false と指定すると、選択された日付がハイライトされないはずなんですが、バグがあって、ハイライトされてしまいます。
javascriptを直すって手もありますが、横着してCSSを上書きしちゃいます。

ちょっと長いですが。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<style>
/* todayHighlightをfalseにしても.activeクラスがついてしまうので上書き */
    .datepicker table tr td.active:hover, 
    .datepicker table tr td.active:hover:hover, 
    .datepicker table tr td.active.disabled:hover, 
    .datepicker table tr td.active.disabled:hover:hover, 
    .datepicker table tr td.active:active, 
    .datepicker table tr td.active:hover:active, 
    .datepicker table tr td.active.disabled:active, 
    .datepicker table tr td.active.disabled:hover:active, 
    .datepicker table tr td.active.active, 
    .datepicker table tr td.active:hover.active, 
    .datepicker table tr td.active.disabled.active, 
    .datepicker table tr td.active.disabled:hover.active, 
    .datepicker table tr td.active.disabled, 
    .datepicker table tr td.active:hover.disabled, 
    .datepicker table tr td.active.disabled.disabled, 
    .datepicker table tr td.active.disabled:hover.disabled, 
    .datepicker table tr td.active[disabled], 
    .datepicker table tr td.active:hover[disabled], 
    .datepicker table tr td.active.disabled[disabled], 
    .datepicker table tr td.active.disabled:hover[disabled]
    {
        background-image: none;
        background-color: white;
        font-weight: normal;
        color: black;
        text-shadow: none;
    }

/* disableの文字色を上書き */
    .datepicker table tr td.active.disabled:hover, 
    .datepicker table tr td.active.disabled:hover:hover, 
    .datepicker table tr td.active.disabled:active, 
    .datepicker table tr td.active.disabled:hover:active,
    .datepicker table tr td.active.disabled.active, 
    .datepicker table tr td.active.disabled:hover.active,
    .datepicker table tr td.active.disabled, 
    .datepicker table tr td.active.disabled.disabled, 
    .datepicker table tr td.active.disabled:hover.disabled, 
    .datepicker table tr td.active[disabled], 
    .datepicker table tr td.active:hover[disabled], 
    .datepicker table tr td.active.disabled[disabled], 
    .datepicker table tr td.active.disabled:hover[disabled]
    {
        color:#999999;
        border-radius: 0;
        background-color: #ddd;
    }
</style>

disableが分かりにくかったので少し修正

デフォルトでは、選択できる日付とできない日付の違いが分かりにくかったので、調節しました。

1
2
3
4
5
/* disableが分かりにくいので塗りつぶす */
    .datepicker td.disabled, .datepicker td.disabled:hover {
        border-radius: 0;
        background-color: #ddd;
    }

bootstrap datepicker

32
Shunsuke Sawada

おすすめの記事

webpackを使ってJSとCSSをコンパイルする(ES6 / Sass)
Turbolinks で Google adsense が正しく表示されない時の対処方法
5
RailsでGoogle mapsを使いこなすためのメモ 2 / 地図デザインのカスタマイズ
2