formに複数の送信ボタン

1つのformで複数ボタンの配置 - masdoiの日記より。

1つのformで複数ボタンを作り、どのボタンが押されたのかをCGI側で判定したい場合があります。

ということでJavaScriptを使用したソースが例示されていたのですが、「複数ボタンを作り、どのボタンが押されたのかをCGI側で判定」という目的に適うものならば、以下のようにHTMLだけでごく簡単に実現できます。

<form action="" method="get">
<input type="submit" name="b1" value="button1">
<input type="submit" name="b2" value="button2">
</form>

サンプルのフォームは action="" method="get" としているので、ボタンを押すとHTMLファイル自身のURLにクエリ文字がついた形 (~/form_sample.html?name=value) でアクセスされます。

(余談ですが、こうするとHTTPサーバを介さなくてもブラウザのみでフォーム送信のテストができるので、自分はよく使っています)

で、このようにすると、

となるので、フォームデータを受け取る側は「パラメタ名b1に値があるか」および「パラメタ名b2に値があるか」をチェックすることで、どちらのボタンが押されたかを判定することができることになります。

自分は以前、「submitボタン(type="submit"のinput要素)のvalue属性はラベル表示のためだけのもの」という誤解をしていたのですが、そうではなくちゃんとname属性を与えれば、送信時にはその name属性値=value属性値 というデータの組が付加されて送られることを後から知りました。さらに、submitボタンに設定されたデータはあくまでボタンを押した時のみ有効となります。そのおかげで上記のようなボタンの区別も容易にできるというわけです。

追記(2008年6月4日)

ブックマークでのコメントを拝見しました。

ysk_lucky-starさんのコメントで気付きましたが、フォームのname属性値(コントロール名)は同じものが複数存在しても構わないので、複数のボタンでname属性を統一し、値で押されたボタンを判別することも可能ですね。データを受ける側は1つのパラメタだけを見ればいいので、むしろそのほうが簡単そうです。以下にサンプルを作ってみました。

また、自分は type="submit"であるinput要素のことだけを想定していたのですが、同様にフォームを送信する働きをもつ要素(フォーム部品)としては、

  • type="image"であるinput要素
  • type="submit"であるbutton要素

もあります。ただ、これらの要素はブラウザにより、どんなデータを送信するかが異なっているため、注意が必要です。こちらもサンプルを。

  • type="image"のinput要素のサンプル
    • Firefoxは、value属性値と合わせてクリックしたポイントの座標データも送られます。
    • IE6, IE7は、座標データのみが送られます。
  • button要素のサンプル
    • Firefoxの動作は、type="submit"であるinput要素と同じ。
    • IE6は、コントロール名に対する値として、value属性値ではなく要素内容が用いられ、更に押していないボタンのデータも合わせて送られます。
    • IE7は、押したボタンのデータのみが送られますが、値にはIE6と同様value属性値ではなく要素内容が用いられます。
  • 内容に画像を持つbutton要素のサンプル
    • Firefoxの動作は、type="submit"であるinput要素と同じ。
    • IE6・IE7の動作は上記button要素の場合と同じですが、送られる要素内容はHTMLソース文字列の形に展開されます。

HTMLフォームを組む際には、HTML仕様書を十分確認しておきましょう。