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はタップし難いですしね。