jQuery DateTimePickerが制御しやすい
この記事は2022/09/29に作成されました。
目次
- 前置き
- Bootstrap-datetimepicker(Tempus Dominus)、flatpickrを検討
- (本題)jQuery DateTimePicker
前置き
日時を選択するシステムを作成する際、HTMLの
<input type="datetime-local">
を使用してきました。
いままでのプロジェクトでは、これで特に問題なく動いていました。
今回あるプロジェクトで
・選択可能・不可能な日時を複数設定できる
・開始日時、終了日時を選択する
といったような処理を入れる事になりました。
上記の input タグでも不可能ではありません。POST された datetime を選択可能な日時かどうか確認し、エラーであれば戻せばデータ上問題はありません。
また、選択不可能な日時を表示しておけば、ユーザーが選択不可能な日時を選ばないように注意させることも可能です。
しかし、実際に入力するユーザー側から見るとどうでしょうか。
選択できるのに ※この日時は選択不可能です などのエラーがでると、入力するのが苦痛になってきます。
なるべくクリック数を少なく、直感的にわかりやすい見た目であったほうがストレスが少ないと思います。
入力可能な日時のみ選択可能にできないか、オプションを確認してみました。
min,max 属性を利用すれば、選択可能な最小日時と最大日時を設定できるようです。
しかしこれだけでは足りません。選択可能または不可能な日時を、複数設定したいのです。
Bootstrap-datetimepicker(Tempus Dominus)、flatpickrを検討
JSならなんとかできるのではないかと思い、いくつかの DateTimePicker を調べ、細かい設定変更が可能な Bootstrap-datetimepicker(Tempus Dominus), flatpickr を使用し、実装してみました。
テーマが選べたり、UIが良かったりと良いことづくしだったのですが、この2つは選択可能(不可能)な時間を設定することができませんでした。
例えば、休日(disableDate)や営業時間(minTime, maxTime)は設定できるが、お昼休憩時間(disable(enable)Time)は設定できないというような状況です。
細かい設定が必要ないプロジェクトではこれらを選択しても良さそうなのですが、今回のプロジェクトでは使えなさそうです。
jQuery DateTimePicker
そんな中、jQueryDateTimePicker というものを見つけました。
この DateTimePicker では、allowDates(array), allowTimes(array), disabledDates(array) を設定可能です!
上記2つと比べると、見た目の自由度(テーマ)が無いですが、自分で css を当てれば自由に変えられそうでしたので、この DateTimePicker を使用することに決定しました。
実装
実装はとても簡単でした。
- npm で install , import または CDN で読み込み
- HTMLにIDを設定(ここはおそらく他の属性でも可。セレクターで要素を取得できれば大丈夫?)
<input id="datetimepicker" type="text" > - jsで設定
jQuery('#datetimepicker').datetimepicker();
これだけで初期設定の DateTImePicker を表示できます!
日本語化するには、setLocale, lang オプションに 'ja' に設定するだけです。
jQuery.datetimepicker.setLocale("ja");
jQuery('#datetimepicker').datetimepicker({
lang: 'ja',
});
土日、祝日に色を付ける
これで、操作時に選択可能・不可能な日時がわかるようになりましたが、ちょっと見た目が均一すぎて混乱してしまうことがあります。
そこで、土日と日本の祝日に色をつけてみようと思います。
土日
.xdsoft_day_of_week6(土曜日)
.xdsoft_day_of_week0(日曜日)
に対して css を設定するだけです。
注意点として、デフォルトの css で結構深くまでネストして設定されているため、上書きするため更に深いネストが必要になるかもしれません。(.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_date.xdsoft_day_of_week0{} のような・・・)
祝日
祝日を取得してくれるようなプログラムは無かったので、他の API を使用することにしました。
今回は Holidays JP API を使用しました。単純で扱いやすいです。
PHP で定期的に取得しに行き、js からも取得できるように json ファイルとして保存しておく形にしました。
あとは js から json を取得し
const jsonData = (await fetch(jsonUrl)
.then((res) => {return res.json();})
.then((data) => { return data;}));
合致する日付に .holiday のような css を付与すれば完了です。
(対象の日付のセル(td)には data 属性で year, month, date が設定されているので、そこで判断する)
(monthは実際の月-1なので注意)
for (let i = 0; i <= Object.keys(jsonData.holidays).length; i++) {
const holidayDtObj = new Date(Object.keys(jsonData.holidays)[i]);
//表示している年月でなければ continue
if (holidayDtObj.getFullYear() !== year || (holidayDtObj.getMonth()) !== month) {
continue;
}
//表示している年月に合致している日付があった場合、 .holidays を付与する
const holidays = document.querySelectorAll('[data-year="' + year + '"][data-month="' + month + '"][data-date="' + holidayDtObj.getDate() + '"]');
for (let i = 0; i < holidays.length; i++) {
holidays[i].classList.add("holiday");
}
DOM には現在表示している年月の日付しか生成されないので、 onShow, onChangeYear, onChangeMonth 内で上記の関数を呼び出せば完了です。
on~系では、引数で選択している日付を取れるので、そこから対象の year, month を取得します。
これで土日・祝に色を付けることができました!
あとがき
今回様々な DateTimePicker を触ってみて、それぞれ違った長所があるなと感じました。
おそらくこれは他のプラグインやライブラリでも言えることだと思います。
これまで特に意識せず、有名だから、日本語のドキュメントが充実しているから というような理由でプラグインやライブラリを使用してきました。
今後は必要な機能やユーザビリティを意識しつつ、目的にあったプラグインを選択し、より洗練されたシステムを作成して行きたいと思います。
プログラマー/A.A