jQueryカレンダーの選択期間を塗りつぶす
久しぶりの更新ですハイ…
さて、とある案件で「カレンダーを表示し、開始日と終了日をクリックしたら、その期間の背景色を塗りつぶし、期間の日数を得たい」というご相談が有りました。
どこかでオープンソース等を見た記憶も有りますし、jQuery.datepickerでも出来そう?な気がしますが、カレンダーをレスポンシブデザインにするため、あえて1から作りました。
サンプルはとりあえず今月~1年間のカレンダーを表示し、二回クリックするとその期間の背景色を変更します。また、常に過去~未来(1月1日~2月1日)へクリックする訳ではないので、未来から過去(2月1日~1月1日)をクリックしても塗りつぶすようにしています。
カレンダーを作る
javascriptのみでカレンダーを作るのは特に難しく有りません。
var date = new Date();
var yy = date.getFullYear();
var mm = date.getMonth();
var dd = date.getDate();
var last = _lastDay(yy,mm);
/*
* 指定月の最終日を得る
*/
function _lastDay(yy, mm){
var dt = new Date(yy, mm, 0);
return dt.getDate();
}
今月の日付と最終日を得て、その分だけカレンダーの日付枠を繰り返すだけです。また、複数月に渡る場合は以下のように月を加算します。
var mm = date.getMonth()+i;
ただ、これだと年を越す場合に問題が出るので、12月を超えた場合は年を加算します。
if(i>1){
if(mm > 12){
var yyyy = yy+1;
var date = new Date(yyyy+"/1/1");
var yy = date.getFullYear();
var mm = (date.getMonth()+i) - (i2+1);
var dd = date.getDate();
}else{
i2++;
}
}
後は前後の空白分を計算し、空の枠を追加します。
こういったものはMyライブラリ的に作成して持っておくと便利かと思います。
期間を塗りつぶす
さて、主題のクリックした期間を塗りつぶす件です。
考え方としては日付に対して何らかの形で数値を割り振っておき、クリックした日付の数値間を塗りつぶすという単純なもの。
例えば、1/1(数値:1) ~1/3(数値:3) とすると、1,2,3の数値が割り振られている枠を塗りつぶすだけ。今回は単純にidに対して数値を割り振っています。
for(var d=1; d<=last; d++){
var ymd = yy+'/'+("0"+mm).slice(-2)+'/'+("0"+d).slice(-2);
html += ' <dd id="'+day_number+'" data-ymd="'+ymd+'">'+d+'</dd>';
day_number++;
}
day_numberは事前に初期化しておき、日付のループ内で+1し、それをidに設定してみました。クリックした時に、このday_numberを比較し、小~大に向けて背景色を変更します。未来から過去へクリックしている場合は逆を行います。
for(i=first_id; i<=$(this).attr('id'); i++){
$("#"+i).addClass('on_bg');
}
あとは、日付をダブルクリックすると無効として初期化し、問題が起きないように。
デートピッカーでフォームに日付が入るのも良いのですが、最近はタブレットやスマートフォンの対応の件も有り、タップでポンポンと選択でき、視覚的効果も含めたものが喜ばれるようです。
ちなみにこの案件では、スマートフォンはこのカレンダーを分解し、1日だけ何月かを表すJun等を小さく表記し、月の継ぎ目なく画面一杯に日付をずら~と並べるスタイルをご希望されました。確かに、小さい画面でdatepickerはタップし難いですしね。




