第16回愛知・名古屋eスポーツ研究会が2021年12月2日(木)、コミュファ eSports Stadium NAGOYA(オンライン併用)にて開催される。
PR: 工場のスマート化支えるエッジコンピューティング、考慮すべきデータの置き所
工場のスマート化の進展により、工場内でもデータの蓄積や活用が加速している。この中で関心が高まっているのが、エッジコンピューティングだ。工場内でのクラウド活用におけるデータの置き所と処理の仕組みの在り方について解説する。…
マット・デイモン 娘の無実を証明するため異国の地で奮闘も、不穏な事態に 「スティルウォーター」予告
2022年1月14日より劇場公開される、マット・デイモン主演のサスペンス・スリラー「スティルウォータ…
「育休中の妻が家の事をするのは当然」の落し穴
「夫は仕事で疲れているから」と育休中に妻が家事・育児を引き受けてしまうと、育休明けにとんでもない事態に?(写真:Ushico/PIXTA)妻が育休期間のとき、妻が家事や育児のほとんどを行い、夫は仕事に全力投球していないでしょうか。妻側は「今は会社で働いていないし、夫に少しでも楽をさせてあげたい」と思いがちですが、一度家事・育児の分担を固定化してしまうと、育休明けにそれを変えるのは容易ではありません。『3000以上の家計を診断した人気FPが教える お金…
HTMLのdialog要素とフォーム機能
こんにちは、
id:nanto_viです。この記事ははてなエンジニアAdvent Calendarの1日目の分です。
Webアプリケーションでモーダルダイアログを実現しようとして苦戦したことはないでしょうか? 自前でHTML、CSS、JavaScriptを組み合わせて実装していくと、フォーカスやスクロールの制御が大変ですよね。そんな悩みを解決してくれるのがHTMLのdialog要素、Webブラウザ組み込みのモーダルダイアログ実装が利用できるという優れものです(モードレスダイアログとしても利用できます)。
dialog要素を使うことで、モーダルダイアログに要求されるJavaScript機能をブラウザが肩代わりしてくれるので、アクセシビリティの確保も簡単になります。
2021年12月現在、ChromeやEdgeはすでにdialog要素に対応しています。FirefoxやSafariの開発版でも対応が進んでおり、主要ブラウザでdialog要素を利用できる日も近いでしょう。
モーダルダイアログを表示する
モーダルダイアログを表示する場合、dialog要素に対するDOMオブジェクト(HTMLDialogElementオブジェクト)のshowModalメソッドを呼び出します。ダイアログを閉じる場合はcloseメソッドを呼び出します。
<p><button type="button" onclick="document.getElementById('ex-dialog-1').showModal()">詳細を表示する</button></p> <dialog id="ex-dialog-1" aria-labelledby="ex-dialog-1-title"> <h3 id="ex-dialog-1-title">詳細</h3> <p>詳細は○○です。</p> <p><button type="button" onclick="this.closest('dialog').close();">閉じる</button></p> </dialog>
詳細
詳細は○○です。
お使いの環境はdialog要素に対応していないため、上の例でダイアログの内容がそのまま表示されています。
なお、showModalメソッドではなくshowメソッドを使うと、モードレスダイアログとして表示されます。
dialog要素とform要素を組み合わせる
ダイアログを閉じるのにHTMLのフォーム機能を使うこともできます。form要素のmethod属性にdialogという値を指定すると、フォーム送信の挙動が「送信先に移動する」のではなく「ダイアログを閉じる」になります(HTTP要求は発生しません)。
<p><button type="button" onclick="document.getElementById('ex-dialog-2').showModal()">詳細を表示する</button></p> <dialog id="ex-dialog-2" aria-labelledby="ex-dialog-2-title"> <form method="dialog"> <h3 id="ex-dialog-2-title">詳細</h3> <p>詳細は○○です。</p> <p><button type="submit">閉じる</button></p> </form> </dialog>
詳細
詳細は○○です。
HTMLのフォーム検証機能を使う
フォーム機能を使えるということは、フォーム検証機能も使えるということです。次の例では、入力欄に何か入力しないと「確定する」ボタンからダイアログを閉じられません。
<p><button type="button" onclick="document.getElementById('ex-dialog-3').showModal()">名前を入力する</button></p> <dialog id="ex-dialog-3" aria-labelledby="ex-dialog-3-title"> <form method="dialog"> <h3 id="ex-dialog-3-title">名前を入力</h3> <p><label>名前: <input type="text" required></label></p> <p><button type="submit">確定する</button></p> </form> </dialog>
名前を入力
なお、ブラウザによってはダイアログ上でEscキーを押下するとキャンセル操作として扱われ、何も入力していなくてもダイアログを閉じられます。
フォーム検証機能を迂回する
フォーム検証をせずにダイアログを閉じたいというときには、いくつか手段があります。
formnovalidate属性を使う
送信ボタンにformnovalidate属性を指定すると、フォーム検証を行わずにフォーム送信が実行されます。
<p><button type="button" onclick="document.getElementById('ex-dialog-4').showModal()">名前を入力する</button></p> <dialog id="ex-dialog-4" aria-labelledby="ex-dialog-4-title"> <form method="dialog"> <h3 id="ex-dialog-4-title">名前を入力</h3> <p><label>名前: <input type="text" required></label></p> <p> <button type="submit" formnovalidate>キャンセル</button> <button type="submit">確定する</button> </p> </form> </dialog>
名前を入力
この場合は送信ボタンの順序が重要になってきます。ブラウザによってはテキスト入力欄でEnterキーを押下したときに、最初に出現する送信ボタンが実行されたものとみなされるからです(暗黙的なフォーム送信)。上の例では「キャンセル」ボタンがデフォルトボタンとみなされ、「名前」入力欄で何も入力せずにEnterキーを押下したときもダイアログが閉じてしまいます。
ちなみに、個人的にはどの送信ボタンがデフォルトボタンなのか指定できるようになると嬉しいのですが、あまり議論は進んでいません。
closeメソッドを使う
「キャンセル」ボタンをデフォルトボタンにしたくなければ、送信ボタン(type="submit")ではなく汎用的なボタン(type="button")にするという手があります。この場合はJavaScriptでダイアログを閉じることになります。
<button type="button" onclick="this.closest('dialog').close();">キャンセル</button> <button type="submit">確定する</button>
submitメソッドを使う
HTMLFormElementオブジェクトのsubmitメソッドを呼び出すことでも、フォーム検証をせずにフォーム送信できます。
<button type="button" onclick="this.form.submit();">キャンセル</button> <button type="submit">確定する</button>
どのボタンが実行されたか判別する
送信ボタンを使ってダイアログを閉じた場合、その送信ボタンのvalueプロパティの値が、ダイアログのreturnValueプロパティの値として設定されます。
<p><button type="button" onclick="document.getElementById('ex-dialog-5').showModal()">名前を入力する</button></p> <p id="ex-dialog-5-output"></p> <dialog id="ex-dialog-5" aria-labelledby="ex-dialog-5-title" onclose="document.getElementById('ex-dialog-5-output').textContent = `「${this.returnValue}」ボタンが実行されました。`;"> <form method="dialog"> <h3 id="ex-dialog-5-title">名前を入力</h3> <p><label>名前: <input type="text" required></label></p> <p> <button type="submit" value="cancel" formnovalidate>キャンセル</button> <button type="submit" value="enter">確定する</button> </p> </form> </dialog>
名前を入力
ダイアログのcloseメソッドの引数に値を指定すると、ダイアログを閉じることとreturnValueプロパティにその値を設定することが一度にできます。
<button type="button" value="cancel" onclick="this.closest('dialog').close(this.value);">キャンセル</button> <button type="submit" value="enter">確定する</button>
終わりに
以上、HTML仕様とWebブラウザの進歩により、様々な機能を簡単に利用できるようになるという話でした。
はてなでは、Web技術を語らいサービスへの活用を探る仲間を募集しています。
狩野英孝、クリスマスにまさかの場所でロケ? みちょぱと仲良くサンタコスプレ披露
タレントのみちょぱこと池田美優とお笑い芸人の狩野英孝が29日、都内で行われた『「LINEギフト」新キャンペーン&新CM発表会』に出席した。>>全ての画像を見るクリスマスらしく、サンタのコスプレで仲良く登場した狩野とみちょぱ。狩野は「この格好で外を歩くと、全く関係ないスタッフも笑顔で『メリークリスマス』って。みんなをハッピーにする格好なんだなって思いました」とコスプレに照れ臭そうな表情。今…