input[type=date]の挙動とDatepicker
input[type=date] を使った時の挙動、実はいまだにブラウザによってまちまち。
Chrome はチープなピッカーを申し訳程度に表示するんだけど、macOS 版の Safari に至ってはピッカーすら出してくれない。ただし iOS、iPad OS 版の Safari はちゃんとしたピッカーを表示してくれる。
なので iPhone、iPad の場合は OS デフォルトのピッカーを、それ以外のブラウザの場合は jQuery でもなんでもいいんだけど Datepicker 的なものを表示するようにしてみた。
まずは基本
まずは基本的によくやるようなパターン。以下のような HTML を用意する。
<input type="text" class="datepicker">
次に以下のような JavaScript を用意する。
$( () => {
$("input.datepicker").datepicker();
});
これで input[type=text] が Datepicker 化はされたけど、input[type=date] がきれいに対応してくれている iPhone や iPad の Safari でも JavaScript ベースの Datepicker が表示されてしまう。
input[type=date]
そこでまずは HTML は以下のようにしてみた。
<input type="date" class="datepicker">
それに伴って JavaScript も直すわけだが、これが一筋縄じゃいかない。やりたいことを整理する。やりたいことは以下の通り。
- iPhone と iPad の時だけ input[type=date] をそのまま使う
- それ以外の時は Datepicker を使う
1番目の iPhone で画面を開いた時の対応は素直にユーザーエージェントを参照すればいいから全く難しくはない。以下のような JavaScript を書けばいい。
$( () => {
if ( is_iPhone == false) {
$("input[type=date]").attr('type', 'text');
$("input.datepicker").datepicker();
}
});
function is_iPhone () {
(navigator.userAgent.indexOf('iPhone;') > -1) ? true : false;
}
こんな感じで iPhone の時は OS デフォルトのピッカーを利用し、それ以外の時は Datepicker 化はすぐできる。
iPad の時も OS デフォルトのピッカーを使う
iPad OS になってから iPad はユーザーエージェントじゃ判定ができなくなってしまった。なので iPad 判定が一番の悩みどころなんだけど、実は window.navigator.standalone ってところに iPhone/iPad の時は値が入っている。要は undefined じゃない(window.navigator.standalone が何を意図している情報なのかはググってもらえれば・・・)。
よって、以下のコードで先に箇条書きにした要件を満たす実装にできる。
<input type="date" class="datepicker">
$( () => {
if ( is_iOS == false) {
$("input[type=date]").attr('type', 'text');
$("input.datepicker").datepicker();
}
});
function is_iOS () {
(navigator.userAgent.indexOf('iPhone;') > -1 || navigator.standalone != undefined ) ? true : false;
}
紆余曲折を経て、やっと要件を満たすことができた。
ちなみにこの辺りのこと、TAppKit ベース になるウェブ版の 10Years の次期アップデートなどのために試行錯誤したんだけど、おかげでいろいろスッキリした。