フォームの date
型の input
要素をクリックするとカレンダーが表示されます。file
型の input
要素をクリックするとファイルピッカーが表示されます。しかし、ユーザーに別の場所をクリックさせて、これらピッカーを JavaScript で動的に表示させたいこともあるでしょう。今回は、それを実現する showPicker()
を紹介します。
なぜ必要なのか?
そもそも、なぜ JavaScript からピッカーを動的に表示させたいのかと疑問に思う人もいるでしょう。ファイルピッカーを例に簡単に説明します。
誰もがご存じの通り、file
型の input
要素は次のようにレンダリングされます。以下はキャプチャ画像ではないので、ご利用のブラウザーによって見た目は異なるはずです。
ご覧の通り file
型の input
要素はとても無骨で飾り気がなく、ウェブサイトのデザインに合わない場合もあります。また、表示される文言を変更することもできません。そのため、この input
要素を CSS で非表示にしたうえで、独自の UI を用意することがあります。その解決方法として、これまでは click()
メソッドが使われてきました。
click() メソッドを使った解決方法
次のファイルピッカーを試してください。どのメジャーなブラウザーでも期待通りに動作するはずです。
このサンプルの HTML と JavaScript は次の通りです。
<input type="file" id="inp1" style="display:none;">
<button type="button" id="btn1">ファイルを選択してください</button>
<output id="out1" for="inp1" value=""></output>
// ボタンがクリックされたときの処理
document.querySelector('#btn1').addEventListener('click', (event) => {
document.querySelector('#inp1').click();
}, false);
// ファイルが選択されたときの処理
document.querySelector('#inp1').addEventListener('change', (event) => {
if (event.target.files.length > 0) {
document.querySelector('#out1').value = event.target.files[0].name;
}
}, false);
input
要素はインラインスタイル display:none
で非表示にしています。JavaScript では、button
要素がクリックされたら、input
要素の DOM オブジェクトの click()
メソッドを呼び出して、疑似的に click
イベントを発生させます。これでファイルピッカーが表示されます。
ファイルピッカーでファイルが選択されると、input
要素で change
イベントが発生しますので、そのイベントのリスナー関数では、選択されたファイルのファイル名を output
要素に出力しています。
click() メソッドの問題
ピッカーはファイルに限った話ではありません。input
要素には file
型のほかにも、date
型のカレンダー日付ピッカー、color
型のカラーピッカーなど、ピッカーが表示されるフォームコントロールは数多くあります。これらの型の input
要素に前述の click()
メソッドの方法を使おうとすると、すべてのブラウザーでうまく機能しません。次のサンプルで試してみましょう。
このサンプルの HTML と JavaScript は次の通りです。
<input type="date" id="inp2" style="width:0px; border-width:0px;">
<button type="button" id="btn2">日付を選択してください</button>
<output id="out2" for="inp2" value=""></output>
// ボタンがクリックされたときの処理
document.querySelector('#btn2').addEventListener('click', (event) => {
document.querySelector('#inp2').click();
}, false);
// 日付が選択されたときの処理
document.querySelector('#inp2').addEventListener('change', (event) => {
document.querySelector('#out2').value = event.target.value;
}, false);
このサンプルが期待通りに動作するのは、この記事執筆時点では Android 版の Chrome だけです。MacOS 版の Safari 16 では、カレンダー日付ピッカーが表示され日付を選択できるものの、ピッカーを消すことができなくなります。ユーザーインタフェースとしてはかなり問題です。それ以外のブラウザーではボタンを押しても反応がありません。
このように、click()
メソッドは、あらゆるフォームコントロールのピッカーにおける解決策にはなりえません。そこで登場したのが、showPicker()
メソッドです。
showPicker() メソッドの使い方
showPicker()
メソッドは input 要素の DOM オブジェクトから呼び出します。前述のサンプルコードの click()
を showPicker()
に書き換えるだけです。以下のサンプルを試してください。ただし、Safari では動作しませんので、Chrome、Edge、Firefox のいずれかでお試しください。
このサンプルの HTML と JavaScript は次の通りです。
<input type="date" id="inp3" style="width:0px; border-width:0px;">
<button type="button" id="btn3">日付を選択してください</button>
<output id="out3" for="inp3" value=""></output>
// ボタンがクリックされたときの処理
document.querySelector('#btn3').addEventListener('click', (event) => {
document.querySelector('#inp3').showPicker();
}, false);
// 日付が選択されたときの処理
document.querySelector('#inp3').addEventListener('change', (event) => {
document.querySelector('#out3').value = event.target.value;
}, false);
showPicker()
メソッドに引数はありません。
Safari のサポート状況
2022 年 9 月に Safari 16 で showPicker()
メソッドがサポートされたとアナウンスされました。しかし、この記事を書いている 2022 年 12 月 31 日時点では動作しませんでした。showPicker()
メソッドそのものは存在しているせいか、エラーにはならず、何事もなかったかのように振舞います。いっそうのことエラーになってくれた方が助かるというのが本音です。
datalist 要素の入力値選択肢リスト
2022 年 12 月 31 日時点では Chrome と Edge に限定した機能になりますが、showPicker()
メソッドは datalist
要素による入力値選択肢リストの表示にも使えます。
このサンプルの HTML と JavaScript は次の通りです。
<input type="text" list="plang-list" id="inp4">
<button type="button" id="btn4">言語を選択してください</button>
<datalist id="plang-list">
<option value="JavaScript"></option>
<option value="Java"></option>
<option value="Python"></option>
<option value="Go"></option>
<option value="C#"></option>
</datalist>
// ボタンがクリックされたときの処理
document.querySelector('#btn4').addEventListener('click', (event) => {
document.querySelector('#inp4').showPicker();
}, false);
datalist
要素による入力値選択肢リストの場合、input
要素を非表示にすると使い勝手が非常に悪いため、このサンプルでは非表示にしていません。
まとめ
前述の通り、この記事の執筆時点で、Safari では showPicker()
メソッドがまともに動作しません。単にサポートしていないならまだしも、機能しないにもかかわらずエラーも出さないというその中途半端さが残念でなりません。
showPicker()
メソッドは自由なフォームコントロールをデザインするうえでは欠かせない存在になるはずです。はやく Safari が showPicker()
メソッドをまともにサポートしてくれることを祈るばかりです。
今回は以上で終わりです。最後まで読んでくださりありがとうございました。それでは次回の記事までごきげんよう。