JavaScript からフォームを送信する方法として form
要素の DOM オブジェクトの submit()
メソッドが良く使われてきましたが、新たに requestSubmit()
メソッドが加わりました。requestSubmit()
メソッドを使うことで、HTML マークアップの恩恵を受けながらも柔軟なフォームを作ることができます。今回は submit()
メソッドと requestSubmit()
メソッドの違い、そして具体的な requestSubmit()
メソッドの使い方を解説します。
requestSubmit() メソッドの概要
requestSubmit()
メソッドは、submit()
メソッドと同様に form
要素の DOM オブジェクトから呼び出すことができるメソッドです。そして、どちらのメソッドも該当のフォームを送信するという点では同じです。次の HTML マークアップをご覧ください。
1 2 3 4 5 6 7 | < form id = "frm" > < label > メールアドレス < input type = "text" name = "mailaddress" > </ label > </ form > < button type = "button" id = "btn" >送信</ button > |
button
要素が form
要素の外にマークアップされている点に注目してください。ボタンを押してもフォームは送信されません。そこで、次の JavaScript を使って、ボタンを押したらフォームを送信するようにします。
1 2 3 | document.querySelector( '#btn' ).addEventListener( 'click' , () => { document.querySelector( '#frm' ).requestSubmit(); }, false ); |
単に form 要素の DOM オブジェクトから requestSubmit()
メソッドを呼び出すだけです。非常に簡単です。しかし、このサンプルでは requestSubmit()
メソッドを submit()
メソッドに置き換えたとしても結果は同じになるため、それらの違いは分かりません。次のサンプルで、その違いを確認してみましょう。
submit() と requestSubmit() の違い
submit()
メソッドと requestSubmit()
メソッドの違いを簡単にまとめると、submit()
メソッドは単にフォームを送信するだけに対して、requestSubmit()
メソッドはユーザーが送信ボタンを押したのと同じように振る舞います。とはいえ、このように説明されても違いが分かりませんよね。具体的には次の違いが発生します。
submit()
ではform
要素でsubmit
イベントが発生しませんが、requestSubmit()
では発生します。submit()
ではマークアップによるフォームバリデーションがバイパスされて無効になりますが、requestSubmit()
では有効になります。
この違いを理解するために、次の HTML マークアップをご覧ください。
1 2 3 4 5 6 7 | < form id = "frm" > < label > メールアドレス < input type = "email" name = "mailaddress" required> </ label > </ form > < button type = "button" id = "btn" >送信</ button > |
変更点は以下の 2 つです。
input
要素のtype
属性を"text"
から"email"
に変更input
要素にrequired
属性を追加
これら 2 つの変更によって、この input
要素はマークアップによるフォームバリデーションの対象になります。もし送信ボタンが form
要素の中にあり、そのボタンを押してフォームを送信しようとすると、input
要素に何かしらの文字列が入力されているかどうか、そして、その文字列がメールアドレスとして適切かどうかがチェックされます。もし適切でないと判断されれば、ブラウザーは input
要素近辺にエラーメッセージを表示してフォームの送信を中止します。
今回のサンプルではボタンが form
要素の外にあるため、マークアップだけではフォームの送信はおろか、フォームバリデーションも機能しません。そこで次の JavaScript コードをご覧ください。
1 2 3 | document.querySelector( '#btn' ).addEventListener( 'click' , () => { document.querySelector( '#frm' ).submit(); }, false ); |
ボタンをクリックすると、form
要素の DOM オブジェクトの submit()
メソッドが呼び出されます。この場合は、フォームバリデーションが無効のまま、強制的にフォームが送信されてしまいます。また、このサンプルでは気づくことはできませんが、form
要素で submit
イベントも発生しません。
では、前述の JavaScript コードを次のコードに置き換えます。
1 2 3 4 5 6 7 8 9 10 | document.querySelector( '#btn' ).addEventListener( 'click' , () => { document.querySelector( '#frm' ).requestSubmit(); }, false ); document.querySelector( '#frm' ).addEventListener( 'submit' , (event) => { const res = window.confirm( '本当に送信してもよろしいですか?' ); if (res === false ) { event.preventDefault(); } }, false ); |
ボタンをクリックすると、form
要素の DOM オブジェクトの requestSubmit()
メソッドが呼び出されます。このため、前述の submit()
メソッドの場合と違い、フォームバリデーションが有効になります。メールアドレス入力に不備があればエラーメッセージが表示され、フォームを送信することはできません。
また、このサンプルでは form
要素で発生する submit
イベントをキャッチし、確認ダイアログを表示します。次のフォームで実際に試してください。
送信ボタンを指定する
一般的にフォームの送信ボタンは 1 つですが、用途が異なる複数のボタンを配置できることをご存じでしょうか。次の HTML マークアップは form
要素は 1 つですが送信ボタンとなる button
要素が 3 つマークアップされています。
1 2 3 4 5 6 7 8 9 10 11 | <form id="frm1"> <label> メールアドレス <input type="email" name="mailaddress" required> </label> <div> <button id="btn1" formaction="/reg1">窓口 1 に登録</button> <button id="btn2" formaction="/reg2">窓口 2 に登録</button> <button id="btn3" formaction="/reg3">窓口 3 に登録</button> </div> </form> |
button
要素に注目してください。formaction
属性に異なるパスがセットされています。これによって、押すボタンによってフォームの送信先が変わることになります。
requestSubmit()
メソッドは、引数に送信ボタンの DOM オブジェクトを引き渡すことで、そのボタンを押したフォーム送信を代行することができます。次の JavaScript コードは「窓口 2 に登録」ボタンの押下と同じ結果になります。つまり、"/reg2"
にフォームを送信します。
1 2 | const btn2 = document.querySelector( '#btn2' ); document.querySelector( '#frm1' ).requestSubmit(btn2); |
ブラウザーのサポート状況
Chrome、Edge、Firefox は以前から requestSubmit()
メソッドをサポートしていましたが、Safari 16 のリリースによって、すべてのメジャーブラウザーでサポートされることになりました。Android はもちろんのこと、iOS でも利用可能です。
HTMLFormElement API: `requestSubmit()` | Can I use…
まとめ
これまで submit()
メソッドで何とかしてきたわけですから requestSubmit()
が無くてもすぐに困ることはないでしょう。しかし、フォームバリデーションなど何でもかんでも JavaScript で何とかするのではなく、HTML マークアップで代替できるものはそれに任せる設計を心がけると、JavaScript のコードもシンプルになって良いのではないでしょうか。
今回は以上で終わりです。最後まで読んでくださりありがとうございました。それでは次回の記事までごきげんよう。