The HTML formaction attribute lets a submit button override the owning form's action URL, so a single form can send data to different destinations depending on which button the user pressed.
formaction は、送信ボタンごとに <form> の送信先URLを上書きするための属性です。
同じ入力欄を使いながら、「下書き保存」と「公開する」を別URLへ送りたいときに役立ちます。
formaction が「どのボタンを押したときだけ」効くのかを説明できる<form action="..."> と formaction の優先関係を迷わず判断できる<button> / <input type="submit"> / <input type="image"> での使い分けを理解できるformmethod / formenctype / formtarget / formnovalidate をボタン単位で切り替えられるformaction って何?ざっくり言うと、formaction は「このボタンで送ったときだけ送信先を変える」ための属性です。
<form action="..."> が決めるformaction で上書きできるformaction は使われない同じフォームでも、押したボタンによって送信先が変わる形を確認します。
まだ送信していません。
HTML
<form action="/submit/publish" method="post">
<label>
件名
<input type="text" name="title">
</label>
<button type="submit">公開する</button>
<button type="submit" formaction="/submit/draft">下書き保存</button>
<button type="submit" formaction="/submit/preview" formtarget="_blank">確認画面へ</button>
</form>
上の例では、最初のボタンは <form> の action をそのまま使い、後ろ2つのボタンはそれぞれ自分の formaction を使います。
まずは <form> に共通の送信先を書き、分岐が必要な送信ボタンにだけ formaction を付けます。
HTML
<form action="/orders/submit" method="post">
<input type="text" name="memo">
<button type="submit">送信する</button>
<button type="submit" formaction="/orders/save-draft">下書き保存</button>
</form>
送信先を分けたい数だけ、送信ボタン側に上書き属性を追加します。
formaction は、フォーム送信時に使うURLを、送信を開始したボタン側で指定する属性です。フォームオーナーの action 属性がある場合は、その値を上書きします。送信ボタンに formaction がなければ、フォーム側の action が使われます。
<button>、<input type="submit">、<input type="image"> に指定します。<form>)の action 属性です。<button>type="submit" なら使えます。type を省略した <button> も、多くの通常ケースでは送信ボタンとして扱われますが、実務では誤解を避けるため type="submit" を明示するのが安全です。
<input type="submit">送信専用の入力部品です。もっとも素直に formaction が使えます。
<input type="image">画像ボタンでも使えます。送信時にはクリック座標も送られる点が追加で絡みますが、送信先の上書きという考え方は同じです。
<button type="button"> や、単なる通常ボタンには送信機能がないため、formaction を書いても送信先の切り替えとしては意味を持ちません。
action との優先関係優先順位はシンプルで、押された送信ボタンに formaction があればそれが最優先、なければフォームの action が使われます。
HTML
<form action="/publish" method="post">
<button type="submit">公開する</button>
<button type="submit" formaction="/draft">下書き保存</button>
</form>
/publish に送信されます。/draft に送信されます。formaction とセットで覚えたいのが、送信ボタン側でフォームの設定を部分的に変えられる仲間です。
formmethodget / post など、送信方法を上書きします。formenctypemultipart/form-data など、POST時のエンコード方式を上書きします。formtarget_blank など、応答の表示先を上書きします。formnovalidateHTML
<form action="/contact/send" method="post">
<input type="email" name="email" required>
<button type="submit">通常送信</button>
<button
type="submit"
formaction="/contact/save"
formnovalidate
>入力途中で保存</button>
</form>
この例では「通常送信」は検証あり、「入力途中で保存」はそのボタンを押したときだけ検証を飛ばせます。
送信ボタンが <form> の外にあっても、form 属性でフォームオーナーを明示すれば formaction を使えます。
HTML
<form id="postForm" action="/posts/publish" method="post">
<input type="text" name="title">
</form>
<button type="submit" form="postForm">公開する</button>
<button type="submit" form="postForm" formaction="/posts/draft">下書き保存</button>
formaction だけ書いても、どのフォームを送るのかが結び付いていなければ動きません。フォーム内に置くか、form で結び付けます。
type="button" に書いていたformaction を書いても送信先は変わりません。form.submit() を直接呼んだformaction を書いたなら、form 属性で対象フォームの id を指定します。formaction で表現したほうが保守しやすく、意図も読み取りやすくなります。formaction を最優先で検討するformmethod もセットで見るformnovalidate を併用するformaction は <form> に書く属性ではなく、送信ボタン側に書く<input> で使えるわけではなく、submit と image で使うformaction は使われないaction を上書きするので、両方が競合したらボタン側を優先するformaction、formmethod など)は不適切formaction を書けば分けられます。formaction だけで method も変わりますか?formmethod を併用します。<form> に formaction を書けますか?action、ボタン単位の上書きが formaction です。formnovalidate を付ける設計が定番です。<input type="image"> でも使えます。