【JavaScript】フォームのカレンダーやファイルピッカーを JavaScript から呼び出す showPicker()

フォームの 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() メソッドをまともにサポートしてくれることを祈るばかりです。

今回は以上で終わりです。最後まで読んでくださりありがとうございました。それでは次回の記事までごきげんよう。

Share