【JavaScript】送信ボタンでフォームを送信したことにする requestSubmit()

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 のコードもシンプルになって良いのではないでしょうか。

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

Share