フォームの date
型の input
要素をクリックするとカレンダーが表示されます。file
型の input
要素をクリックするとファイルピッカーが表示されます。しかし、ユーザーに別の場所をクリックさせて、これらピッカーを JavaScript で動的に表示させたいこともあるでしょう。今回は、それを実現する showPicker()
を紹介します。
なぜ必要なのか?
そもそも、なぜ JavaScript からピッカーを動的に表示させたいのかと疑問に思う人もいるでしょう。ファイルピッカーを例に簡単に説明します。
誰もがご存じの通り、file
型の input
要素は次のようにレンダリングされます。以下はキャプチャ画像ではないので、ご利用のブラウザーによって見た目は異なるはずです。
ご覧の通り file
型の input
要素はとても無骨で飾り気がなく、ウェブサイトのデザインに合わない場合もあります。また、表示される文言を変更することもできません。そのため、この input
要素を CSS で非表示にしたうえで、独自の UI を用意することがあります。その解決方法として、これまでは click()
メソッドが使われてきました。
click() メソッドを使った解決方法
次のファイルピッカーを試してください。どのメジャーなブラウザーでも期待通りに動作するはずです。
このサンプルの HTML と JavaScript は次の通りです。
1 2 3 | < input type = "file" id = "inp1" style = "display:none;" > < button type = "button" id = "btn1" >ファイルを選択してください</ button > < output id = "out1" for = "inp1" value = "" ></ output > |
1 2 3 4 5 6 7 8 9 10 11 | // ボタンがクリックされたときの処理 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 は次の通りです。
1 2 3 | < input type = "date" id = "inp2" style = "width:0px; border-width:0px;" > < button type = "button" id = "btn2" >日付を選択してください</ button > < output id = "out2" for = "inp2" value = "" ></ output > |
1 2 3 4 5 6 7 8 9 | // ボタンがクリックされたときの処理 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 は次の通りです。
1 2 3 | < input type = "date" id = "inp3" style = "width:0px; border-width:0px;" > < button type = "button" id = "btn3" >日付を選択してください</ button > < output id = "out3" for = "inp3" value = "" ></ output > |
1 2 3 4 5 6 7 8 9 | // ボタンがクリックされたときの処理 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 は次の通りです。
1 2 3 4 5 6 7 8 9 | < 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 > |
1 2 3 4 | // ボタンがクリックされたときの処理 document.querySelector( '#btn4' ).addEventListener( 'click' , (event) => { document.querySelector( '#inp4' ).showPicker(); }, false ); |
datalist
要素による入力値選択肢リストの場合、input
要素を非表示にすると使い勝手が非常に悪いため、このサンプルでは非表示にしていません。
まとめ
前述の通り、この記事の執筆時点で、Safari では showPicker()
メソッドがまともに動作しません。単にサポートしていないならまだしも、機能しないにもかかわらずエラーも出さないというその中途半端さが残念でなりません。
showPicker()
メソッドは自由なフォームコントロールをデザインするうえでは欠かせない存在になるはずです。はやく Safari が showPicker()
メソッドをまともにサポートしてくれることを祈るばかりです。
今回は以上で終わりです。最後まで読んでくださりありがとうございました。それでは次回の記事までごきげんよう。