The JavaScript requestSubmit() method asks a form to submit as if a submit button were activated, so validation, the submit event, and the chosen submitter all participate in the normal submission flow.
requestSubmit() は、フォームを「送信ボタンが押されたのと同じ流れ」で送信し、検証・submit イベント・送信ボタンごとの差まで反映させるためのAPIです。
requestSubmit() と submit() の違いを、検証・イベント・送信ボタンの観点で説明できるrequestSubmit(submitter) で、どの送信ボタンとして送るかを明示できるSubmitEvent.submitter を使って「どのボタンで送られたか」を受け取れるformmethod や formnovalidate などの form* 属性がどこで効くかを判断できるrequestSubmit() って何?ざっくり言うと、requestSubmit() は「フォームを強制送信する」ではなく、「送信ボタンが押された扱いで送信をお願いする」ためのメソッドです。
submit イベントが発火する:preventDefault() で止められるrequestSubmit() は、HTMLFormElement に対して「送信を要求する」メソッドです。submit() と違い、通常の送信ボタンを押したときに近い流れで処理されます。
対象は form 要素です。つまり const form = document.querySelector('form'); のように取得した HTMLFormElement で使います。
submit イベントを発火し、リスナー側で preventDefault() による中止ができるsubmitter として指定し、その formaction / formmethod / formenctype / formnovalidate / formtarget を反映できるsubmitter にすること(TypeError)NotFoundError)submit() のように検証やイベントを飛ばして送ることsubmit() との最大の違いです。submit イベントがフォーム自身で発火します。イベントオブジェクトは SubmitEvent で、submitter からどのボタン扱いだったかを取得できます。name があれば、そのボタンの情報も送信データに含まれます。<input type="image"> でも同様です。JavaScript
const form = document.querySelector('#profileForm');
form.requestSubmit();
まずは「form.requestSubmit() で通常の送信フローに乗せる」と覚えるのが最短です。
JavaScript
const form = document.querySelector('#postForm');
const publishButton = document.querySelector('#publishButton');
form.requestSubmit(publishButton);
送信ボタンごとに formmethod や name/value が違うなら、どのボタン扱いで送るかを明示します。
submit() と何が違う?下のデモは実際の送信は止めつつ、requestSubmit() と submit() の違いをログで見える化したものです。
requestSubmit()submit イベントが発火するpreventDefault() で止められるsubmit()submit イベントが発火しないJavaScript
const form = document.querySelector('#compareForm');
form.addEventListener('submit', (event) => {
event.preventDefault();
console.log('submit event fired');
});
form.requestSubmit(); // 検証と submit イベントを通る
form.submit(); // 検証も submit イベントも通らない
requestSubmit() の戻り値は undefined です。成功/失敗を真偽値で返すAPIではありません。form* 属性や name/value を反映したいなら、明示的にボタンを渡します。<button type="submit"> と <input type="submit">、<input type="image"> です。form owner が対象フォームでなければ NotFoundError になります。見た目が近くても所属フォームが違えば使えません。formnovalidate は効く?formnovalidate があれば、その送信では検証をスキップできます。つまり「下書き保存だけ検証なし」のような分岐が作れます。submit イベントはどこで発火する?event.submitter から取得します。submitter を使うと何がうれしい?複数の送信ボタンを持つフォームでは、「どのボタンで送ったか」が業務ロジックの分岐になります。
JavaScript
form.addEventListener('submit', (event) => {
event.preventDefault();
console.log(event.submitter?.name); // intent
console.log(event.submitter?.value); // save / publish
});
form.requestSubmit(publishButton);
submit() と混同しやすいポイントrequestSubmit() = 即送信submit イベントの流れに入ります。そこで止まることがあります。submit() でも同じsubmit() は検証も submit イベントも通しません。送信前のロジックがあるフォームでは意味が大きく変わります。submit イベントはボタンで発火するSubmitEvent.submitter を見ます。requestSubmit() を呼べば、ブラウザ標準の検証と送信フローに戻せます。JavaScript
const form = document.querySelector('#contactForm');
const sendButton = document.querySelector('#sendButton');
const customButton = document.querySelector('#customSend');
customButton.addEventListener('click', () => {
const ok = window.confirm('送信しますか?');
if (!ok) return;
form.requestSubmit(sendButton);
});
requestSubmit() に渡すと、検証とイベントを壊さずに前処理を挟めます。事故1:form.submit() を使ってしまい、submit イベント内の Ajax 分岐や分析タグが走らない。
回避:通常の送信フローを通したいなら requestSubmit() に置き換える。
事故2:公開ボタンの formmethod="post" を効かせたいのに、引数なしの requestSubmit() を呼んでしまう。
回避:requestSubmit(publishButton) のように対象ボタンを明示する。
事故3:送信ボタンではない通常ボタンを渡して TypeError になる。
回避:type="submit" の有無とフォーム所属を確認する。
切り分けの順番:event.submitter → event.defaultPrevented → form.checkValidity() → ボタンの form* 属性、の順で見ると原因を追いやすいです。
type="submit" ボタンを用意してキーボード送信と支援技術の期待に合わせます。submit()submit イベントを飛ばして直接送るメソッドです。通常フローを通したいなら用途が違います。checkValidity()reportValidity()SubmitEvent.submittersubmit イベント時に、どの送信ボタンが起点だったかを取り出します。requestSubmit()submit イベントを飛ばすのは submit()SubmitEvent.submitterrequestSubmit(submitter) の引数には送信ボタンしか渡せないformaction / formmethod 差分は submitter 指定が効くrequestSubmit() は click() と同じ?requestSubmit() を呼ぶとどうなる?novalidate や formnovalidate がなければ)。requestSubmit() へ戻す使い方は自然です。ただし二重送信防止は別で必要です。submit() へ落とすと挙動差が出る点は理解しておきます。submit イベントが走らないsubmit() を呼んでいる。確認:呼び出し元。解決:requestSubmit() を使う。submit() / novalidate / formnovalidate。確認:フォーム属性とボタン属性。解決:通常フローへ戻す。submit イベントを見ていない、または submit() で飛ばしている。確認:event.submitter。解決:requestSubmit(submitter) を使う。TypeError が出るtype="submit"。解決:送信ボタンだけを渡す。NotFoundError が出るbutton.form === form。解決:所属フォームを揃える。submit イベント)を通したい → requestSubmit()requestSubmit(submitter)submit() を検討submit イベント、起点ボタンは event.submitter で見るcheckValidity()、event.submitter、ボタンの form* 属性から追う