JavaScript からフォームを送信する方法として form
要素の DOM オブジェクトの submit()
メソッドが良く使われてきましたが、新たに requestSubmit()
メソッドが加わりました。requestSubmit()
メソッドを使うことで、HTML マークアップの恩恵を受けながらも柔軟なフォームを作ることができます。今回は submit()
メソッドと requestSubmit()
メソッドの違い、そして具体的な requestSubmit()
メソッドの使い方を解説します。
requestSubmit() メソッドの概要
requestSubmit()
メソッドは、submit()
メソッドと同様に form
要素の DOM オブジェクトから呼び出すことができるメソッドです。そして、どちらのメソッドも該当のフォームを送信するという点では同じです。次の HTML マークアップをご覧ください。
<form id="frm">
<label>
メールアドレス
<input type="text" name="mailaddress">
</label>
</form>
<button type="button" id="btn">送信</button>
button
要素が form
要素の外にマークアップされている点に注目してください。ボタンを押してもフォームは送信されません。そこで、次の JavaScript を使って、ボタンを押したらフォームを送信するようにします。
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 マークアップをご覧ください。
<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 コードをご覧ください。
document.querySelector('#btn').addEventListener('click', () => {
document.querySelector('#frm').submit();
}, false);
ボタンをクリックすると、form
要素の DOM オブジェクトの submit()
メソッドが呼び出されます。この場合は、フォームバリデーションが無効のまま、強制的にフォームが送信されてしまいます。また、このサンプルでは気づくことはできませんが、form
要素で submit
イベントも発生しません。
では、前述の JavaScript コードを次のコードに置き換えます。
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 つマークアップされています。
<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"
にフォームを送信します。
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 のコードもシンプルになって良いのではないでしょうか。
今回は以上で終わりです。最後まで読んでくださりありがとうございました。それでは次回の記事までごきげんよう。